本篇记录搭建、测试ELK应用栈的过程。
Logstash 安装和使用
安装运行
Logstash依赖于Java,所以需要预先安装jre,建议1.8版本及以上。然后在官网可以直接下载二进制压缩文件,解压即可。
创建最简单的示例
Logstash管道有两个最基本元素,输入和输出,和一个可选的元素,拦截器。输入插件从一个输入源中消费数据,拦截器插件按照你指定的方式修改数据,然后输出插件将数据写入到一个目的地。
想要验证Logstash的安装是否成功,可以运行最基本的Logstash管道:
1 | cd logstash |
2 | bin/logstash -e 'input { stdin { } } output { stdout {} }' |
-e
标志可以直接通过命令行指定配置,从而让你快速的测试配置而不用多次修改一个配置文件。这个示例中的管道从标准输入stdin
中获取输入,然后用一个结构化的格式把数据移动到标准输出stdout
。
在启动Logstash完成之后,看到Pipline started
提示后,可以在命令行中输入hello world
,你会看到:
1 | hello world |
2 | 2018-01-25T09:26:53.134Z caih-OptiPlex-7050 hello world |
Logstash在信息中添加了时间戳和主机名。
使用Logstash解析日志
前例中,我们创建了一个最基本的Logstash管道用来测试Logstash是否启动成功。实际应用中,Logstash管道会复杂很多,它会有多个不同类型的输入,有拦截器,还有输出插件。
直接使用Logstash跟踪日志文件
Logstash也可以不借助Filebeat,直接跟踪日志文件。
这里我们写一个简单的shell脚本,名为log.sh,每一秒钟往日志文件里输出一个时间戳,然后跟踪这个日志文件。
1 | # /bin/bash |
2 | while : |
3 | do |
4 | current=`date "+%Y-%m-%d %H:%M:%S"` |
5 | echo $current >> log.log |
6 | sleep 1s |
7 | done |
使用命令nohup bash log.sh &
让这个脚本在后台执行。然后tail -f log.log
就可以看到日志文件在不断增加。
回到logstash的目录下bin文件夹,创建一个简单的配置文件,名为logstash.conf:
1 | input { |
2 | file { |
3 | path => ["/home/caih/docker/logstash/log/log.log"] |
4 | } |
5 | } |
6 | output { |
7 | stdout{} |
8 | } |
这个配置非常简单,就是在追踪刚才写的日志作为输入,然后在命令行输出。
执行命令./logstash -f logstash.conf
,稍等之后就可以看到日志中打印的时间戳出现啦,同时每一条日志前面会有logstash添加的时间戳和主机名。这时候遇到了一个问题,就是logstash运行之前的那些历史日志,会有乱序。我怀疑是多个线程同时收集日志导致的顺序问题。这时候修改config文件夹里面的logstash.yml,将pipieline.worker改为1,这个情况有了好转,但是仍然偶尔可见顺序问题,尚有待解决。
可以注意到,每次重启logstash之后,日志都是从上次的结束为止开始输出的,那么如何每次都从日志文件的开头开始输出呐?可以修改配置如下:
1 | input { |
2 | file { |
3 | path => ["/home/caih/docker/logstash/log/log.log"] |
4 | start_position => "beginning" |
5 | sincedb_path => "/dev/null" |
6 | } |
7 | } |
8 | output { |
9 | stdout{} |
10 | } |
Logstash跟踪日志的时候,标记追踪位置的数据存储在sincedb中,这里sincedb_path就是指定sincedb文件的位置,然后把它配置为linux中自带的空位置,就实现了每次从头开始的目的。
注意,start_position只是说每次从sincedb中标记的起点开始,不是从文件头开始,所以只添加这一项是不行的。
然后同样的,可以把文件位置改为系统日志:
1 | input { |
2 | file { |
3 | path => ["/var/log/*.log"] |
4 | type => "system" |
5 | start_position => "beginning" |
6 | sincedb_path => "/dev/null" |
7 | } |
8 | } |
9 | output { |
10 | stdout{} |
11 | } |
可以看到系统日志的情况。
借助Filebeat采集日志
这部分我们创建一个Logstash管道,使用Filebeat将Apache的日志作为输入,解析这些日志,然后从中创建特定的、命名规范的字段,然后把数据输入到Elasticsearch集群中。这里使用配置文件来定义管道,而不是使用命令行参数。
关于Filebeat
Logstash可以Filebeat配合使用来收集日志,那么Filebeat是个什么东西呐?
Filebeat是一个本地文件的日志信息收集器。安装后可以作为你服务端的代理,Filebeat监控日志目录或者指定的日志文件,不断输出文件然后将他们发送到Elasticsearch和Logstash进行索引。
Filebeat的工作模式是这样的:你启动Filebeat之后,它会开启一个或者多个勘探者(prospector)来跟踪本地路径下你指定的日志文件。对于每一个勘探者定位到的文件,Filebeat会启动一个收割者(harvester)。每个收割者读取单个日志文件,发送到libbeat,libbeat会聚合所有时间,然后发送到你配置好的输出中。
Filebeat的安装很简单,在Ubuntu上只需要执行:
1 | curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.1.2-amd64.deb |
2 | sudo dpkg -i filebeat-6.1.2-amd64.deb |
安装完成之后,可以在/etc/filebeat/filebeat.yml文件中查看和更改配置。在Docker环境中,这个文件的位置是在/usr/share/filebeat/filebeat.yml。
这里以一个简单的配置为例:
1 | filebeat.prospectors: |
2 | - type: log |
3 | enabled: true |
4 | paths: |
5 | - /var/log/*.log |
6 | #- c:\programdata\elasticsearch\logs\* |
更详细的文档格式可以参看官方文档,这里只配置一个简单的栗子。
配置Filebeat来发送日志行到Logstash
在创建Logstash管道之前,需要配置Filebeat用来发送日志到Logstash。Filebeat客户端是一个轻量级,资源友好型工具,用来从服务端的文件中收集日志,然后发送这些日志到Logstash实例中处理。Filebeat的设计理念是高可用和低延时。Filebeat有一个宿主机上轻量的资源占用,而且Beats input
插件将Logstash实例上的资源需求做到了最小化。
创建Filebeat的配置文件名为filebeat.yml,内容如下:
1 | filebeat.prospectors: |
2 | - type: log |
3 | paths: |
4 | - /home/caih/docker/logstash/log/log.log |
5 | output.logstash: |
6 | hosts: ["127.0.0.1:5044"] |
其中的paths就是需要跟踪的日志地址。
然后修改Logstash的配置文件:
1 | input { |
2 | beats { |
3 | port => "5044" |
4 | } |
5 | } |
6 | output { |
7 | stdout { codec => rubydebug } |
8 | } |
然后分别启动两者就可以了,启动Filebeat:filebeat -e -c /home/caih/docker/filebeat/filebeat.yml -d "publish"
;启动Logstash:./logstash -f logstash.conf
,随后就可以看到日志源源不断地在命令行出现啦!
Elasticsearch 安装和使用
安装运行
Elasticsearch的安装非常简单,需要依赖只有Java 1.8之后的版本。然后在官网下载文件,解压文件即可。
进入解压后的文件夹,bin目录下有名为Elasticsearch的可执行文件,执行./elasticsearch
就可以启动了。
./elasticsearch --help
查看命令帮助,可以使用./elasticsearch -d
在后台执行,不在当前命令行输出日志。
配置
进入config文件夹可以看到配置文件,其中elasticsearch的配置是在elasticsearch.yml中,另外的jvm.options可以修改Java虚拟机的相关配置,log4j2.properties可以修改el本身的日志配置。
在elasticsearch.yml中,修改netword.host的值为0.0.0.0,然后就可以其他主机访问了。其他常用的配置还包括集群名称,节点名称,日志地址,端口号等等,更多的信息不再赘述。
在浏览器输入ip:9200,可以看到返回:
1 | { |
2 | "name" : "t_ksdEI", |
3 | "cluster_name" : "elasticsearch", |
4 | "cluster_uuid" : "LdO3LVVyRPGwTARorxrNBA", |
5 | "version" : { |
6 | "number" : "5.5.3", |
7 | "build_hash" : "9305a5e", |
8 | "build_date" : "2017-09-07T15:56:59.599Z", |
9 | "build_snapshot" : false, |
10 | "lucene_version" : "6.6.0" |
11 | }, |
12 | "tagline" : "You Know, for Search" |
13 | } |
这样表示Elasticsearch启动成功。
添加一条文档
在命令行输入:
1 | curl -XPUT 'localhost:9200/customer/doc/1?pretty&pretty' -H 'Content-Type: application/json' -d' |
2 | > { |
3 | > "name": "John Doe" |
4 | > } |
5 | > ' |
然后就添加了一条最简单的文档,稍后可以在Kibana中看到。
Kibana 安装和使用
Kibana的安装同样简单,同样依赖于Java,官网下载tar包解压,然后进入bin目录,使用命令./kibana --help
可以查看启动参数。
输入./kibana serve
即可启动,这里需要注意与Elasticsearch版本是否匹配。我这里用的都是最新版6.1.2。Kiana默认寻找得是本地9200端口的Elasticsearch,如果要指定别的地方的实例,可以在/config/kiban.yml中修改。还有一点,Kibana默认host是本地,所以要修改为0.0.0.0然后才能在其他机器上访问。
输入ip:5601就可以看到Kibana的ui界面了,刚开始会让你输入一个index pattern,可以先输入*匹配所有索引,然后再Discover中就可以看到Elasticsearch中的数据了。
从日志文件到Kibana
日志到Logstash已经联通,Elasticsearch和Kibana也连上了,现在只需要把Logstash的output设置为Elasticsearch。
修改logstash.conf如下:
1 | input { |
2 | file { |
3 | path => ["/home/caih/docker/logstash/log/log.log"] |
4 | } |
5 | } |
6 | output { |
7 | elasticsearch { hosts => ["localhost:9200"] } |
8 | } |
然后Logstash默认的索引是以logstash-开头,所以把kibana中的index pattern修改为logstash-*就可以过滤结果了。这时候在discover部分就可以看到每秒钟一条的时间戳。
Kibana默认的配置中,这里的信息是不自动刷新的,所以想要修改刷新频率,在Management -> advance中,把timepicker:refreshIntervalDefaults
这一项修改为{ "display": "5 seconds", "pause": false, "value": 5000 }
,然后就可以看到日志五秒刷新一次,不断更新。
以上就是ELK栈收集、处理、展示日志最简单的demo。