elk产生的场景:
在微服务开发过程中,一般都会利用多台服务器做分布式部署,如何能够把分散在各个服务器中的日志归集起来做分析处理,是一个微服务服务需要考虑的一个因素。
搭建一个日志系统
搭建一个日志系统需要考虑一下一些因素:
利用什么技术,是自己实现还利用现成的组件
日志需要定义统一的格式
日志需要拥有一个锚点来进行全局跟踪
第一个问题,针对我们小公司来说,基本没有自己的研发能力,绝对是选用第三方开源的组件了。ELK配置比较简单,有现成的UI界面,容易检索日志信息,是首选。
第二个问题,利用log4j2定义好统一的日志格式,利用logstash过滤日志内容。
第三个问题,全局跟踪的ID有几种生产方式,一种是利用UUID或者生成随机数,一种是利用数据库来生成sequence number,还可以通过自定义一个id生成服务来获取。考虑到自身服务的需要,这里选用生成随机数来实现。
ELK+Filebeat 集中式日志解决方案详解
Elasticsearch:分布式搜索和分析引擎,具有高可伸缩、高可靠和易管理等特点。基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。通常被用作某些应用的基础搜索引擎,使其具有复杂的搜索功能;
Logstash:数据收集引擎。它支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到用户指定的位置;
Kibana:数据分析和可视化平台。通常与 Elasticsearch 配合使用,对其中数据进行搜索、分析和以统计图表的方式展示;
Filebeat:ELK 协议栈的新成员,一个轻量级开源日志文件数据搜集器,基于 Logstash-Forwarder 源代码开发,是对它的替代。在需要采集日志数据的 server 上安装 Filebeat,并指定日志目录或日志文件后,Filebeat 就能读取数据,迅速发送到 Logstash 进行解析,亦或直接发送到 Elasticsearch 进行集中式存储和分析
ELK 常用架构及使用场景介绍
在这个章节中,我们将介绍几种常用架构及使用场景。
最简单架构
在这种架构中,只有一个 Logstash、Elasticsearch 和 Kibana 实例。Logstash 通过输入插件从多种数据源(比如日志文件、标准输入 Stdin 等)获取数据,再经过滤插件加工数据,然后经 Elasticsearch 输出插件输出到 Elasticsearch,通过 Kibana 展示。详见图 1。
图 1. 最简单架构
这种架构非常简单,使用场景也有限。初学者可以搭建这个架构,了解 ELK 如何工作。
Logstash 作为日志搜集器
这种架构是对上面架构的扩展,把一个 Logstash 数据搜集节点扩展到多个,分布于多台机器,将解析好的数据发送到 Elasticsearch server 进行存储,最后在 Kibana 查询、生成日志报表等。详见图 2。
图 2. Logstash 作为日志搜索器
这种结构因为需要在各个服务器上部署 Logstash,而它比较消耗 CPU 和内存资源,所以比较适合计算资源丰富的服务器,否则容易造成服务器性能下降,甚至可能导致无法正常工作。
Beats 作为日志搜集器
这种架构引入 Beats 作为日志搜集器。目前 Beats 包括四种:
Packetbeat(搜集网络流量数据);
Topbeat(搜集系统、进程和文件系统级别的 CPU 和内存使用情况等数据);
Filebeat(搜集文件数据);
Winlogbeat(搜集 Windows 事件日志数据)。
Beats 将搜集到的数据发送到 Logstash,经 Logstash 解析、过滤后,将其发送到 Elasticsearch 存储,并由 Kibana 呈现给用户。详见图 3。
图 3. Beats 作为日志搜集器
这种架构解决了 Logstash 在各服务器节点上占用系统资源高的问题。相比 Logstash,Beats 所占系统的 CPU 和内存几乎可以忽略不计。另外,Beats 和 Logstash 之间支持 SSL/TLS 加密传输,客户端和服务器双向认证,保证了通信安全。
因此这种架构适合对数据安全性要求较高,同时各服务器性能比较敏感的场景。
引入消息队列机制的架构
到笔者整理本文时,Beats 还不支持输出到消息队列,所以在消息队列前后两端只能是 Logstash 实例。这种架构使用 Logstash 从各个数据源搜集数据,然后经消息队列输出插件输出到消息队列中。目前 Logstash 支持 Kafka、Redis、RabbitMQ 等常见消息队列。然后 Logstash 通过消息队列输入插件从队列中获取数据,分析过滤后经输出插件发送到 Elasticsearch,最后通过 Kibana 展示。详见图 4。
图 4. 引入消息队列机制的架构
这种架构适合于日志规模比较庞大的情况。但由于 Logstash 日志解析节点和 Elasticsearch 的负荷比较重,可将他们配置为集群模式,以分担负荷。引入消息队列,均衡了网络传输,从而降低了网络闭塞,尤其是丢失数据的可能性,但依然存在 Logstash 占用系统资源过多的问题。
基于 Filebeat 架构的配置部署详解
前面提到 Filebeat 已经完全替代了 Logstash-Forwarder 成为新一代的日志采集器,同时鉴于它轻量、安全等特点,越来越多人开始使用它。这个章节将详细讲解如何部署基于 Filebeat 的 ELK 集中式日志解决方案,具体架构见图 5。
图 5. 基于 Filebeat 的 ELK 集群架构
因为免费的 ELK 没有任何安全机制,所以这里使用了 Nginx 作反向代理,避免用户直接访问 Kibana 服务器。加上配置 Nginx 实现简单的用户认证,一定程度上提高安全性。另外,Nginx 本身具有负载均衡的作用,能够提高系统访问性能。
Filebeat + ELK 安装
ELK 官网对于每种软件提供了多种格式的安装包(zip/tar/rpm/DEB),以 Linux 系列系统为例,如果直接下载 RPM,可以通过 rpm -ivh path_of_your_rpm_file
直接安装成系统 service。以后就可以使用 service 命令启停。比如 service elasticsearch start/stop/status
。很简单,但缺点也很明显,就是不能自定义安装目录,相关文件放置比较分散。
实际使用中更常用是使用 tar 包安装。每种软件产品的安装过程非常相似,所以下面仅以 Elasticsearch 为例简述安装过程。
软件包
实验环境中使用的4个软件包都是5.1.1版本,也可以到官网http://www.elastic.co/下载最新的版本
环境:
配置hosts两台服务器网络通畅
agent1 安装es1,agent3安装es2 做成集群,后期可能还会用到redis,redis提供的功能相当于kafka,收集logstatsh发来的数据,es从redis中提取数据。
agent1 安装kibana 做数据展示
agent3安装logstatsh 做数据收集
filebeat安装在需要收集日志的服务器上
为了安全起见 elasticsearch 5.x默认不能用root启动,所以 需要用elasticsearch 用户启动ES
首先关闭防火墙和Selinux,Redhat7.2关闭防火墙的方法如下
systemctl status firewall
systemctl stop firewalld
systemctl disable firewall
systemctl enable firewall
由于es logstatsh kibana基于java 开发,所以安装jdk ,jdk版本不要过低,否则会提醒升级jdk。
安装elasticsearch(agent1,agent3全都安装es)
在agent1,agent3上安装一个大于1.8的jdk版本,然后解压5.1.1的es的tar.gz
一个 Elasticsearch 集群中一般拥有三种角色的节点,master、data 和 client。
master:master 节点负责一些轻量级的集群操作,比如创建、删除数据索引、跟踪记录集群中节点的状态、决定数据分片(shards)在 data 节点之间的分布;
data:data 节点上保存了数据分片。它负责数据相关操作,比如分片的 CRUD,以及搜索和整合操作。这些操作都比较消耗 CPU、内存和 I/O 资源;
client:client 节点起到路由请求的作用,实际上可以看做负载均衡器。
配置文件中有两个与集群相关的配置:
node.master:默认 true。True 表示该节点是 master 节点;
node.data:默认 true。True 表示该节点时 data 节点。如果两个值都为 false,表示是 client节点。
一个集群中不一定有 client 节点,但是肯定有 master 和 data 节点。
默认第一个启动的节点是 master。Master 节点也能起到路由请求和搜索结果整合的作用,所以在小规模的集群中,无需 client 节点。但是如果集群规模很大,则有必要设置专门的 client。
logstash是一个管理日志和事件的工具,你可以收集它们,解析它们,并存储它们以供以后使用(例如日志搜索),logstash有一个内置的web界面,用来搜索你的所有日志。logstash在部署时有两种运行模式:standalone和centralized:
* standalone:standalone的意思是所有的事情都在一台服务器上运行,包括日志收集、日志索引、前端WEB界面都部署在一台机器上。
* centralized:就是多服务器模式,从很多服务器运输(ship)日志到一台总的日志(collector)服务器上用来索引和查找。
需要注意的是logstash本身并没有什么shipper和collector这种说法,因为不论是运输日志的进程还是汇集总的日志的进程运行的都是同一个程序,只是使用的配置文件不同而已。
elasticsearch:
基于lucene的开源搜索引擎,是一个分布式的搜索分析系统,主要特点有:realtime data、real time analytics、distributed、high availability、multi-tenancy、fulltext search、document oriented、conflict management、schema free、restful api等等。
kibana3:
可视化日志和数据系统,作为WEB前端可以很容易的和elasticsearch系统结合。kibana有版本2和版本3的区分,版本2采用ruby编写,部署起来很麻烦,需要安装很多ruby依赖包(目前网上多是这个版本的部署),版本3采用纯html+css编写,因此部署起来很方便,解压即用
最基本的elk
每台需要被收集的日志 服务器上安装Logstash,然后过Logstash将日志数据流发送给ES服务器,ES服务器将收集到的数据流发送的Kibana,kibana将数据流展示出来
大概就是这样的原理
Elesticsearch部署
es1的配置:ip地址为192.168.137.11
[root@agent1 ~]# grep -n '^[a-Z]' /usr/local/elasticsearch-5.1.1/config/elasticsearch.yml
17:cluster.name: my-application
23:node.name: node-2
33:path.data: /var/lib/elasticsearch
37:path.logs: /var/log/elasticsearch
55:network.host: 192.168.137.11
56:network.bind_host: 192.168.137.11
57:network.publish_host: 192.168.137.11
58:http.port: 9201
59:node.master: false
60:node.data: true
61:http.enabled: true
62:http.cors.enabled: true
63:http.cors.allow-origin: "*"
76:discovery.zen.ping.unicast.hosts: ["192.168.137.11","192.168.137.13"]
es2的配置,设置es2为master节点:ip地址为192.168.137.13
[root@agent3 ~]# egrep -v "^#|^$" /usr/local/elasticsearch-5.1.1/config/elasticsearch.yml
cluster.name: my-application
node.name: ${HOSTNAME}
node.master: true
node.data: true
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 192.168.137.13
network.bind_host: 192.168.137.13
network.publish_host: 192.168.137.13
http.enabled: true
http.cors.enabled: true
http.cors.allow-origin: "*"
http.port: 9200
discovery.zen.ping.unicast.hosts: ["192.168.137.13","192.168.137.11"]
[root@agent3 ~]#
启动es1
su - elasticsearch
/usr/local/elasticsearch-5.1.1/bin/elasticsearch -d
补充:
默认情况下,Elasticsearch在前台运行,将其日志打印到标准输出(stdout),并可以通过按Ctrl-C停止。 要将Elasticsearch作为daemon运行,请在命令行上指定-d,并使用-p选项将进程ID记录在文件中:
bin/elasticsearch -d -p pid
日志消息记录在$ES_HOME/logs 文件夹中 要关闭Elasticsearch,请删除pid文件中记录的进程ID:
kill `cat pid`
或者:
su - elasticsearch -c "/usr/local/elasticsearch-5.1.1/bin/elasticsearch &"
查看java进程
[root@agent1 bin]# ps -ef | grep java
501 5153 5121 0 11:11 pts/1 00:01:53 /usr/local/jdk1.8.0_121//bin/java -Xms2g -Xmx2g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -server -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j.skipJansi=true -XX:+HeapDumpOnOutOfMemoryError -Des.path.home=/usr/local/elasticsearch-5.1.1 -cp /usr/local/elasticsearch-5.1.1/lib/elasticsearch-5.1.1.jar:/usr/local/elasticsearch-5.1.1/lib/* org.elasticsearch.bootstrap.Elasticsearch
root 6529 5328 0 16:53 pts/4 00:00:00 grep java
查看es1的启动端口
[root@agent1 bin]# netstat -tulnp | grep java
tcp 0 0 ::ffff:192.168.137.11:9201 :::* LISTEN 5153/java
tcp 0 0 ::ffff:192.168.137.11:9300 :::* LISTEN 5153/java
[root@agent1 bin]#
可以看到es的9201端口已经启动
Elasctisearch 节点默认使用 9300 端口寻找集群,所以必须开启这个端口。
测试:
在es机器上访问:
curl 'http://localhost:9200'
curl 'http://localhost:9200/?pretty'
或者在浏览器窗口中输入 http://localhost:9200/?pretty
es1结果如下:
es集群搭建
集群的搭建也非常简单,保证cluster_name一致, node_name不一致就好了,
可以在同一个网段自动发现新节点,也可以在配置文件的discovery.zen.ping.unicast.hosts属性中指定集群的节点IP;node2的es端口改成9201
判断设备的角色
http://192.168.137.13:9200/_cat/master?v
http://192.168.137.11:9201/_cat/nodes?v
*代表master
Logstash部署
1、解压logstash-5.1.2.tar.gz
tar xvzf logstash-5.1.2.tar.gz
在/usr/local/logstash-5.1.1/config/下创建配置文件logstash-simple.conf
input { stdin { } }
output {
elasticsearch { hosts => ["localhost:9200"] }
stdout { codec => rubydebug }}
3、启动logstash
bin/logstash -f /usr/local/logstash-5.1.1/config/logstash-simple.conf
4、执行curl http://192.168.137.13:9200/,提示下面的信息说明启动成功。
Kibana部署
解压kibana并且安装和启动
修改配置文件config/kibana.yml ,在21行左右去掉elasticsearch.url前面注释
server.port: 5601
server.host: "192.168.137.11"
elasticsearch_url: "http://192.168.137.13:9200"
cd /usr/local/kibana-5.1.1-linux-x86_64 && nohup ./bin/kibana &
通过 http://IP:5601 访问kibana
curl -XGET 'localhost:9200/_cat/indices?v&pretty' #查看索引
[root@agent3 tmp]# curl -XGET '192.168.137.13:9200/_cat/indices?v&pretty'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana QJEp9a-eT2iysoLIg9e6HQ 1 1 1 0 6.3kb 3.1kb
green open twitter OzTyY2dlTL6HcPns4OuCHQ 5 1 1 0 10.1kb 5kb
Elasticsearch5.1.1安装问题集锦
使用Elasticsearch5.X 必须安装jdk1.8
问题1:
org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException:
can not run elasticsearch
as
root
解决方案:
因为安全问题elasticsearch 不让用root用户直接运行,所以要创建新用户
建议创建一个单独的用户用来运行ElasticSearch
创建elasticsearch用户组及elasticsearch用户
groupadd asticsearch
useradd elasticsearch -g elasticsearch -p elasticsearch
然后修改安装配置文件
chown elasticsearch:elasticsearch /usr/local/elasticsearch-5.1.1 -R
另外指定的日志文件和数据文件也需要递归修改用户和组,启动程序时切换到自定的elasticsearch用户,./elasticsearch -d在后台的方式启动
root 启动elasticsearch报错
/bin/elasticsearchException in thread "main" java.lang.RuntimeException: don't run elasticsearch as root. at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:93) at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:144) at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:285) at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:35)
Refer to the log for complete error details.12345671234567
解决方案:
bin/elasticsearch -Des.insecure.allow.root=true
启动失败
Exception in thread "main" java.lang.RuntimeException: don't run elasticsearch as root.
解释:为“防止attacker 获取root权限”, 如果是RPM包安装,会自动创建elastsearch组和elastsearch用户,设置好密码,换一个用户启动即可
问题2:
使用elasticsearch启动ES后 又会遇到以下问题
ERROR: bootstrap checks failed
max file descriptors [10240] for elasticsearch process likely too low, increase to at least [65536]
max number of threads [1024] for user [elsearch] likely too low, increase to at least [2048]
max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
[2016-11-14T10:22:17,569][INFO ][o.e.n.Node ] [mysteel-node1] stopping ...
[2016-11-14T10:22:17,615][INFO ][o.e.n.Node ] [mysteel-node1] stopped
[2016-11-14T10:22:17,615][INFO ][o.e.n.Node ] [mysteel-node1] closing ...
[2016-11-14T10:22:17,638][INFO ][o.e.n.Node ] [mysteel-node1] closed
max virtual memory areas vm.max_map_count [65530] likely too low,increase to at least [262144]
解决方案:
切换到root用户
vi /etc/security/limits.conf
添加如下内容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
vi /etc/security/limits.d/20-nproc.conf
修改如下内容:
* soft nproc 1024
#修改为
* soft nproc 2048
max file descriptors [10240] for elasticsearch process likely too low, increase to at least [655360]
vi /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
并执行命令:
sysctl -p
然后,重新启动elasticsearch,即可启动成功。
或者直接用命令行临时的方式进行更改进行修改值:
sysctl -w vm.max_map_count=262144
查看修改结果:
sysctl -a|grep vm.max_map_count
ulimit -Hn
65536
Increase RLIMIT_MEMLOCK, soft limit: XXXXX, hard limit: XXXXX
es为了性能考虑,推荐关掉swap,并锁定一部分mem,按照日志中的指引操作即可
问题3:
外网访问9200端口系统redhat7.2安装elasticsearch后本机可以访问127.0.0.1:9200,但不能访问【公网IP:9200】
解决方案
修改配置文件 config/elasticsearch.yml
network.host: 0.0.0.0
http.port: 9200
注意关闭防火墙和selinux
问题4:
cannot allocate memory
解决方案: 虚拟机内存不够,关掉虚拟机,重新加大内存分配,原先是512M,现在分配到2000M
前辈经验:
问个问题,ES集群搭建为什么官方建议3台或者5台,2台哪里不好?
ES集群属于分布式,分布式系统默认是3个副本
奇数才能做仲裁,偶数怎么做仲裁
技术来源于生活
恩,这里的仲裁怎么解释
架设多个人投票,你说偶数投票能有什么结果
必须投同一或是不同意
偶数就会造成脑裂
elasticsearch-head使用
5.X版本 有了x-pack 和cerebro 就够了
2.X 集群有配置head 但是我们几乎没用
5.X的集群 我们用的x-pack和cerebro
logstash规则学习
logstash是日志收集、分析组件,启动需要指点启动脚本,脚本中定义日志的input、output已经filter等日志过滤规则。
2.2.1. input
常用的input包括以下:
标准输入
input {
stdin {}
}
文件输入
input {
file {
path => "/home/yarn/hadoop-2.5.2/logs/*.log"
type => "hadoop"
codec => multiline {
# Grok pattern names are valid! :)
pattern => "^%{TIMESTAMP_ISO8601} "
negate => true
what => previous
}
}
}
tcp输入
input {
tcp {
port => 8888
mode => "server"
ssl_enable => false
}
}
syslog输入
input {
syslog {
port => "514"
}
}
log4j输入
input {
log4j {
type => "test-log4j"
port => 4560
}
}
说明:使用log4j类型的input需要在log4j配置文件中配置logstash输出。
log4j.properties:
log4j.rootLogger=DEBUG, logstash
###SocketAppender###
log4j.appender.logstash=org.apache.log4j.net.SocketAppender
log4j.appender.logstash.Port=4560
log4j.appender.logstash.RemoteHost=172.18.84.66
log4j.appender.logstash.ReconnectionDelay=60000
log4j.appender.logstash.LocationInfo=true
log4j.xml 添加以下配置
把新定义的appender添加到root logger里面,可以跟其他已有logger共存
2.2.2. output
常用的output包括:
标准输出
output {
stdout {
codec => rubydebug
}
}
输出到elasticsearch
output {
elasticsearch {
hosts => "xdata66"
}
stdout{
codec => rubydebug
}
}
发送email
output {
email {
to => ""
}
}
2.2.3. 数据处理
grok
...
说明:logstash任务是个agent,可以在一个节点或者多个节点同时启动多个agent。
Filebeat + ELK 配置
Filebeat 和 ELK 的安装很简单,比较难的是如何根据需求进行配置。这个章节选取了几个比较典型且重要的配置需求和配置方法。
Filebeat 与 Logstash 安全通信
用户可以使用 TLS 双向认证加密 Filebeat 和 Logstash 的连接,保证 Filebeat 只向可信的 Logstash 发送加密的数据。同样的,Logstash 也只接收可信的 Filebeat 发送的数据。
这个功能默认是关闭的。可通过如下步骤在配置文件中打开:
生成 Filebeat 自签名证书和 key 文件
因为试验用,所以这里使用的都是自签名证书。如何使用 openssl 生成自签名证书,网上有很多教程,Elastic github 上也直接提供了参考指令。
openssl req -subj '/CN=hostname/' -x509 -days $((100*365)) -batch -nodes -newkeys rsa:2048 -keyout ./pki/tlk/provate/filebeat.key -out ./pki/tls/certs/filebeat.crt
这条指令生成自签名证书和 key 文件。读者需要把 hostname 部分改成实际环境的 hostname,或者是 IP 地址。
生成 Logstash 自签名证书和 key 文件
命令类似。
Filebeat 配置
首先把 Logstash 的自签名证书传送到 Filebeat 所在服务器。然后,对 logstash output 部分的 tls 配置作如下修改:
tls:
## logstash server 的自签名证书。
certificate_authorities: ["/etc/pki/tls/certs/logstash.crt"]
certificate: "/etc/pki/tls/certs/filebeat.crt"
certificate_key: "/etc/pki/tls/private/filebeat.key"
其中:
certificate_authorities:CA 证书,即用来签署证书的证书。这里表示配置 Filebeat 使其信任所有由该 CA 证书发行的证书。因为自签名证书的发行者和证书主体相同,所以这里直接使用 Logstash 证书使 Filebeat 信任使用该证书的 Logstash server;
certificate & certificate_key:Filebeat 证书和 key 文件。Filebeat 将使用它们向 Logstash server 证明自己的可信身份。
Logstash 配置
同 Filebeat 配置类似,首先把 Filebeat client 上的证书复制到 Logstash server 上,然后作如下修改。
12345678910input {
beats {
port => 5044
ssl => true
ssl_certificate_authorities => ["/etc/pki/tls/certs/filebeat.crt"]
ssl_certificate => "/etc/pki/tls/certs/logstash.crt"
ssl_key => "/etc/pki/tls/private/logstash.key"
ssl_verify_mode => "force_peer"
}
}
其中:
ssl:true 表示开启 Logstash 的 SSL/TLS 安全通信功能;
ssl_certificate_authorities:配置 Logstash 使其信任所有由该 CA 证书发行的证书;
ssl_certificate & ssl_key:Logstash server 证书和 key 文件。Logstash 使用它们向 Filebeat client 证明自己的可信身份;
ssl_verify_mode:表明 Logstash server 是否验证 Filebeat client 证书。有效值有 peer 或 force_peer。如果是 force_peer,表示如果 Filebeat 没有提供证书,Logstash server 就会关闭连接。
Filebeat 实现 log rotation
通俗的说,log rotation 是指当日志文件达到指定大小后,把随后的日志写到新的日志文件中,原来的日志文件重命名,加上日志的起止时间,以实现日志归档的目的。
Filebeat 默认支持 log rotation,但需要注意的是,Filebeat 不支持使用 NAS 或挂载磁盘保存日志的情况。因为在 Linux 系列的操作系统中,Filebeat 使用文件的 inode 信息判断当前文件是新文件还是旧文件。如果是 NAS 或挂载盘,同一个文件的 inode 信息会变化,导致 Filebeat 无法完整读取 log。
虽然 Filebeat 默认支持 log rotation,但是有三个参数的设置需要留意。
registry_file:这个文件记录了当前打开的所有 log 文件,以及每个文件的 inode、当前读取位置等信息。当 Filebeat 拿到一个 log 文件,首先查找 registry_file,如果是旧文件,就从记录的当前读取位置处开始读取;如果是新文件,则从开始位置读取;
close_older:如果某个日志文件经过 close_older 时间后没有修改操作,Filebeat 就关闭该文件的 handler。如果该值过长,则随着时间推移,Filebeat 打开的文件数量很多,耗费系统内存;
scan_frequency:Filebeat 每隔 scan_frequency 时间读取一次文件内容。对于关闭的文件,如果后续有更新,则经过 scan_frequency 时间后,Filebeat 将重新打开该文件,读取新增加的内容。
Elasticsearch 集群
Elasticsearch 启动时会根据配置文件中设置的集群名字(cluster.name)自动查找并加入集群。Elasctisearch 节点默认使用 9300 端口寻找集群,所以必须开启这个端口。
一个 Elasticsearch 集群中一般拥有三种角色的节点,master、data 和 client。
master:master 节点负责一些轻量级的集群操作,比如创建、删除数据索引、跟踪记录集群中节点的状态、决定数据分片(shards)在 data 节点之间的分布;
data:data 节点上保存了数据分片。它负责数据相关操作,比如分片的 CRUD,以及搜索和整合操作。这些操作都比较消耗 CPU、内存和 I/O 资源;
client:client 节点起到路由请求的作用,实际上可以看做负载均衡器。
配置文件中有两个与集群相关的配置:
node.master:默认 true。True 表示该节点是 master 节点;
node.data:默认 true。True 表示该节点时 data 节点。如果两个值都为 false,表示是 client 节点。
一个集群中不一定有 client 节点,但是肯定有 master 和 data 节点。默认第一个启动的节点是 master。Master 节点也能起到路由请求和搜索结果整合的作用,所以在小规模的集群中,无需 client 节点。但是如果集群规模很大,则有必要设置专门的 client。
Logstash 使用 grok 过滤
日志数据一般都是非结构化数据,而且包含很多不必要的信息,所以需要在 Logstash 中添加过滤插件对 Filebeat 发送的数据进行结构化处理。
使用 grok 正则匹配把那些看似毫无意义、非结构化的日志数据解析成可查询的结构化数据,是目前 Logstash 解析过滤的最好方式。
Grok 的用户不需要从头开始写正则。ELK github 上已经写好了很多有用的模式,比如日期、邮箱地址、IP4/6、URL 等。具体查看这里。除此之外,还有 grok 正则表达式的debug 工具,能方便快速检验所写表达式是否正确。
下面是一个 grok 的配置实例,读者可以适当修改满足你的需求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
filter {
grok {
match => {
"message" => [
"\[(?< Logtime >(%{MONTHNUM}/%{MONTHDAY}/%{YEAR})\s+%{TIME}\s+%{WORD})\]\s+%{BASE16NUM}\s+(?< LogSource >([\w|\S]+))\s+%{WORD:LogLevel}\s+(?< LogStr >[\w|\W]*)",
"\[(?< Logtime >(%{MONTHNUM}/%{MONTHDAY}/%{YEAR})\s+%{TIME}\s+%{WORD})\]\s+%{BASE16NUM}\s+%{WORD:LogLevel}\s+(?< LogStr >[\w|\W]*(\\n)+)"
]
}
remove_field => ["message"]
}
if "_grokparsefailure" in [tags] {
grok {
match => ["message", "(?< LogStr >[\w|\W]+)"]
remove_field => ["message"]
remove_tag => ["_grokparsefailure"]
add_field => {
LogSource => "-"
LogLevel => "-"
LogTime => "-"
}
}
}
}
|
第一个 grok 列了两种正则表达式,如果第一种不匹配,则自动使用第二种。如果第二种也没有匹配,则匹配失败,log 数据中添加一个"_grokparsefailure"域,表明 grok 匹配失败了。读者可根据实际需求决定如何处理匹配失败的数据。这里,对于匹配失败的,将再匹配一次,并给没有匹配上的域赋予默认值"-",这样使得日志数据格式统一,都含有 4 个域:Logtime、LogSource、LogLevel、LogTime,便于后续数据搜索和展示。
配置 Nginx 实现用户认证
关于这部分配置的教程很多,这里就不赘述了。
遇到的典型问题
问题:Filebeat 如何读取多个日志目录?
如果 Filebeat 所在 server 上运行有多个 application servers,各自有不同的日志目录,那 Filebeat 如何同时读取多个目录,这是一个非常典型的问题。
解决方案:通过配置多个 prospector 就能达到要求。在配置文件的 prospectors 下,每个"-"表示一个 prospector,每个 prospector 包含一些配置项,指明这个 prospector 所要读取的日志信息。如下所示:
1
2
3
4
5
6
7
8
9
|
prospectors:
-
paths:
- /home/WLPLog/*.log
# 其他配置项,具体参考 Elastic 官网
-
paths:
- /home/ApacheLog/*.log
# 其他配置项,具体参考 Elastic 官网
|
问题:Filebeat 如何区分不同日志来源?
还是上题中提到的场景,Filebeat 虽然能读取不同的日志目录,但是在 Logstash 这边,或者是 Elasticsearch 这边,怎么区分不同 application server 的日志数据呢?
解决方案:Filebeat 的配置项 fields 可以实现不同日志来源的区分。用法如下:
1
2
3
4
5
6
7
8
9
10
11
|
prospectors:
-
paths:
- /home/WLPLog/*.log
fields:
log_source: WLP
-
paths:
- /home/ApacheLog/*.log
fields:
log_source: Apache
|
在 fields 配置项中,用户可以自定义域来标识不同的 log。比如上例中的"log_source"就是笔者自定义的。如此,从 Filebeat 输出的 log 就有一个叫做 log_source 的域表明该 log 的实际来源。
问题:如何配置 Logstash 与 Elasticsearch 集群通信?
我们知道 Logstash 使用 Elasticsearch 输出插件就能把数据发送到 Elasticsearch 进行存储和搜索。Elasticsearch 插件中有个 hosts 配置项说明 Elasticsearch 信息。但是假如是一个 Elasticsearch 集群,应该怎么配置 hosts?
解决方案:最简单的做法是把集群中所有的 Elasticsearch 节点的 IP 或者是 hostname 信息都在 hosts 中配上(它支持数组)。但是如果集群比较大,或者是集群节点变动频繁的话,还需要维护这个 hosts 值,不太方便。比较推荐的做法是只配集群中某个节点的信息,可以是 client 节点,也可以是 master 节点或者是 data 节点。因为不管是哪个节点,都知道该它所在集群的信息(集群规模,各节点角色)。这样,Logstash 与任意节点通信时都会先拿到集群信息,然后再决定应该给哪个节点发送数据输出请求。
问题:如何在 Kibana 显示日志数据?
解决方案:当数据存储在 Elasticsearch 端之后就可以在 Kibana 上清楚的展示了。首先在浏览器上打开 Kibana 页面。如果使用了 Nginx,就使用 Nginx 配置的 URL;否则就是http://yourhostname:5601。
创建日志索引。Logstash 发送的数据,默认使用 logstash 前缀作为数据索引。见图 7。
图 7. Kibana 创建索引页面
点击 Create,再选择 Discover 页面就能看见 Logstash 发送的数据了,如图 8 所示。
图 8. 数据展示页面
Kibana 具体的使用,比如如何创建日志 visualization,如何将 visualization 添加到 dashboard,如何在 Kibana 上搜索日志,这些可以参考官网。
结束语
本文首先简要介绍了 ELK 协议栈的几种典型的架构及其使用场景,然后针对 Filebeat 的架构,详细说明了如何安装和配置。限于篇幅,同时由于某些基本配置,官网有详尽的说明,所以本文只是选取了几个比较重要,同时官网上说得不是很明确的地方作说明,希望对大家有帮助。
ELK 论坛上有不少内部人士热心帮忙解答用户的问题。如果读者在使用过程中有不懂的,搜索了很久也找不到答案的问题,可以在 ELK 论坛寻求帮助。
参考资料
查看ELK 官方网站,了解 ELK+Beats 等产品的介绍;
搜索ELK 论坛,寻找关于 ELK 在实际使用中的问题及解答;
查看文章部署和扩展 ELK,了解更多关于如何扩展 ELK 架构的知识;
参考使用 Nginx 实现 Kibana 登陆认证博客,学习如何配置 Nginx 作为 Kibana 的反向代理,且实现登陆认证;
查阅Filebeat 文档,系统全面地学习 Filebeat 的安装配置细节;
查阅Elasticsearch 文档,系统全面地学习 Elasticsearch 的安装配置细节;
查阅Logstash 文档,系统全面地学习 Logstash 的安装配置细节;
查阅Kibana 文档,系统全面地学习 Kibana 的安装配置细节。
博客参考地址:
http://www.ibm.com/developerworks/cn/opensource/os-cn-elk-filebeat/index.html?ca=drs-&utm_source=tuicool&utm_medium=referral
http://m.blog.csdn.net/article/details?id=51280058
http://www.ibm.com/developerworks/cn/opensource/os-cn-elk-filebeat/index.html?ca=drs-&utm_source=tuicool&utm_medium=referral
elastic官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html
https://www.gitbook.com/book/chenryn/elk-stack-guide-cn/details
https://www.elastic.co/guide/en/elasticsearch/reference/master/shard-allocation-filtering.html
https://kibana.logstash.es/content/kibana/v5/source-code-analysis/kbnindex.html 中文 指南