前言
随着互联网的发展,分布式的集群环境越来越多被应用,这同时也带来了另一个问题,在分布式的环境中,各个节点的信息被分散到不同的物理机器上,这导致问题的排查也越来越困难,平时我们跟踪问题使用最多的方式就是查询日志,但是在分布式的环境中,要在成百上千的节点中找出错误日志也是非常困难的,ELK的出现解决了这个问题。
什么是ELK
ELK是Elasticsearch、Logstash、Kibana三个工具的简称:
- Elasticsearch(ES)是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
- Logstash是一个完全开源的工具,他可以对你的日志进行收集、分析,并将其存储供以后使用(如,搜索)。
- Kibana也是一个开源和免费的工具,他Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。
想要了解一个系统,必须想了解系统的架构,我们先来看一下ELK的部署架构:
这个图说明,我们的应用节点把日志数据写入到Logstash之后,Logstash再将日志写入到ES中,然后由Kibana从ES中取出日志数据并进行统计分析,最后展示给用户浏览器。
在这个过程中,Logstash担任日志收集,ES负责存储,Kibana负责展示。
顺便说明一下,在ELK系统中,用来解决了分布式的日志收集存储和分析的问题。实际上ES是可以单独使用的,并且可以用来作为存储和搜索引擎,ES本身也提供了非常强大的rest api和查询语法。
部署ELK
本文使用的是最新的5.0.0-rc1版本,部署在fedora 24 64位操作系统上,下载链接:
- Elasticsearch: https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.0.0-rc1.tar.gz
- Logstash: https://artifacts.elastic.co/downloads/logstash/logstash-5.0.0-rc1.tar.gz
- Kibana: https://artifacts.elastic.co/downloads/kibana/kibana-5.0.0-rc1-linux-x86_64.tar.gz
现在我们开始部署ELK,从架构图中我们知道,ES是最基础的功能,因此必须先部署ES,ES依赖于JAVA,所以需要想安装jdk,建议使用jdk8或以上的版本,本文使用jdk8。
部署ES
先下载好ES的部署包,然后解压:
[kael@localhost ~]$ tar -xvf elasticsearch-5.0.0-rc1.tar.gz
解压,然后进入文件夹,查看一下文件:
es的部署十分简单,作为实验性的部署,我们不用改任何配置,直接进入bin目前,启动es即可:
[kael@localhost ~]$ cd bin/
[kael@localhost ~]$ ./elasticsearch
可以看到如下启动日志:
这样就启动完成了,如果要停止的话直接按下ctrl+c
即可。
注:这里es有一个启动异常,从错误信息看应该是某个功能在Linux的内核中没有,先不管他,不影响我们部署和查看效果,之后学习在解决这个问题。
es默认监听端口是9200,我们可以重新打开一个终端,输入:
[kael@localhost ~]$ curl http://localhost:9200
可以看到
[kael@localhost ~]$ curl http://localhost:9200
{
"name" : "VBGdn28",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "1dnn9vtxRpmcnyLqV4vn9g",
"version" : {
"number" : "5.0.0-rc1",
"build_hash" : "13e62e1",
"build_date" : "2016-10-07T16:52:58.798Z",
"build_snapshot" : false,
"lucene_version" : "6.2.0"
},
"tagline" : "You Know, for Search"
}
展示了配置的cluster_name和name,以及安装的ES的版本等信息,这说明es已经启动完成。
部署Logstash
接下来我们部署Logstash,同样将部署包下载好,解压:
[kael@localhost Downloads]$ tar -xvf logstash-5.0.0-rc1.tar.gz
进入Logstash的目录:
这里我们需要做些配置,首先自己创建一个目录,建议将我们的配置文件放在config目录下:
[kael@localhost logstash-5.0.0-rc1]$ vim config/log4j_to_es.conf
这里我们直接创建log4j_to_es.conf
文件,并编辑这个文件,内容如下:
# For detail structure of this file
# Set: https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html
input {
# For detail config for log4j as input,
# See: https://www.elastic.co/guide/en/logstash/current/plugins-inputs-log4j.html
log4j {
mode => "server"
host => "0.0.0.0" #allow all ip to connect
port => 4567
}
}
filter {
#Only matched data are send to output.
}
output {
# For detail config for elasticsearch as output,
# See: https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html
elasticsearch {
action => "index" #The operation on ES
hosts => "localhost:9200" #ElasticSearch host, can be array.
index => "applog" #The index to write data to.
}
}
注意,这里配置了input和output两大块,input表示的是logstash收集日志的入口,也表示我们需要收集日志的应用请求的地址,output表示logstash写出的服务器,这里配置成es的地址。
编辑完成之后保存,使用如下命令启动logstash:
[kael@localhost logstash-5.0.0-rc1]$ ./bin/logstash -f config/log4j_to_es.conf
可以看到如下启动日志:
为了测试logstash是否启动成功,我们写一个简单的java程序来测试,使用log4j,因为log4j可以很方便的支持远程写日志。
我们先创建好一个maven的java工程:
然后加入log4j的依赖:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
接下来写一个简单的Main函数:
package elk.demo;
import org.apache.log4j.Logger;
/**
* Created by KAEL on 2016/10/24.
*/
public class Main {
private static final Logger LOGGER = Logger.getLogger(Main.class);
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
LOGGER.error("Info log [" + i + "].");
Thread.sleep(500);
}
}
}
只是直接通过log4j打10行错误日志而已,但是要把这个结果写入logstash,所以要配置一下log4j:
log4j.rootLogger=INFO,console
# for package com.demo.elk, log would be sent to socket appender.
log4j.logger.com.demo.elk=DEBUG, socket
# appender socket
log4j.appender.socket=org.apache.log4j.net.SocketAppender
log4j.appender.socket.Port=4567
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.layout=org.apache.log4j.PatternLayout
log4j.appender.socket.layout.ConversionPattern=%d [%-5p] [%l] %m%n
log4j.appender.socket.ReconnectionDelay=10000
# appender console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%-5p] [%l] %m%n
要注意这里的log4j.appender.socket.Port
和log4j.appender.socket.RemoteHost
需要配置logstash服务的ip和端口,然后我们运行 一下main函数:
没有报错说明我们日志写入成功,如果出现如下错误:
log4j:ERROR Could not connect to remote log4j server at [localhost]. We will try again later.
可以尝试关闭logstash服务器的防火墙,保证网络联通再试试。
部署Kibana
下载好Kibana的部署包并解压:
[kael@localhost Downloads]$ tar -xvf kibana-5.0.0-rc1-linux-x86_64.tar.gz
进入Kibana的目录:
启动Kibana之前我们需要一些配置,这个配置文件在config/kibana.yml
中:
[kael@localhost kibana-5.0.0-rc1-linux-x86_64]$ vim config/kibana.yml
将一下几行的注释去掉:
server.port: 5601
server.host: "localhost"
elasticsearch.url: "http://localhost:9200"
kibana.index: ".kibana"
注意,这里的server.host
最好是kibana所在的服务器ip,这样才能在其他的机器上访问。
修改完成后保存即可。
启动Kibana:
[kael@localhost kibana-5.0.0-rc1-linux-x86_64]$ ./bin/kibana
可以看到如下启动日志:
现在我们可以通过kibana服务器的ip和端口访问kibana了:
到这里我们就把完整的ELK环境部署好了,可以做进一步的学习和开发了。