ELK实际上就是ElasticSearch,Logstash,Kibana的缩写,是日志收集分析的一种解决方案。html
elk是目前比较新也发展比较快的一套数据分析套件,其中Elasticsearch是用来做为存储和查询引擎的,kibana则是位于其之上的一个UI(更偏向于聚合汇总分析),而logstash则是属于ETL工具(数据的提取转换插入)。
在具体的使用过程当中,目前以为logstash算是比较鸡肋的,由于适用的场景有限,并且要扩展必须本身实现。我的建议,若是对es比较熟悉的,彻底能够不须要用这个。本身用es加个river插件,那个效果也不错。前端
ELK简单架构
java
日志收集系统架构总体架构
linux
简单来说他具体的工做流程就是Logstash agent监控并过滤日志,将过滤后的日志内容发给Redis(这里的redis只处理队列不作存储),Logstash index将日志收集在一块儿交给全文搜索服务ElasticSearch,能够用ElasticSearch进行自定义搜索,经过Kibana来结合 自定义搜索进行页面展现nginx
此外 logstash 的收集方式分为 standalone 和 centralized。
standalone 是全部功能都在一个服务器上面,自发自收,centralized 就是集中收集,一台服务器接收全部shipper(我的理解就是logstash agent)的日志。
其实 logstash自己不分 什么 shipper 和 collector ,只不过就是配置文件不一样而已,咱们此次按照集中的方式来测试git
这里的Logstash分为index和agent两种角色,也能够说是收集方式分为standalone和centralized两种。standalone是全部功能都在一个服务器上面,自发自收,centralized就是集中收集,一台服务器接收全部shipper(我的理解就是logstash agent)的日志。(其实logstash自己不分什么shipper和collector ,只不过就是配置文件不一样而已)。Logstash的agent和indexer分开部署,多台agent负责监控、过滤日志,index负责收集日志并将日志交给ElasticSearch作搜索,经过Kibana来结合自定义搜索进行页面展现。Redis其实是起到了缓冲消峰的做用,不然并发访问量大的时候ES会被拖垮的github
192.168.0.1 logstash index,ElasticSearch,kibana,JDK
192.168.0.2 logstash agent,JDK
192.168.0.3 redisweb
由于上一篇文章已经写过Docker如何安装ES环境了,这里咱们直接继承上一次安装好的Docker镜像,因此重点只介绍Logstash和Kibana的安装,本文只是简单的单机ELK环境,后续会逐步完善ELK+Redis的环境,甚至会把ELK单独拆开三个Docker镜像使用redis
安装Logstash(本文使用的是logstash的1.5.4版本)docker
# 下载Logstash $ curl -O https://download.elastic.co/logstash/logstash/logstash-1.5.4.tar.gz # 解压ES压缩包 $ tar -zxvf logstash-1.5.4.tar.gz # 在{LOGSTASH_HOME}下新建一个conf目录,在里面新建一个配置文件logstash.conf $ cd logstash-1.5.4 $ mkdir conf $ cd conf # 编辑logstash.conf以下面的配置 $ vi logstash.conf # 启动logstash $ cd {LOGSTASH_HOME}/bin/ $ ./logstash -f ../conf/logstash.conf
注意
由于Java的默认heap size,回收机制等缘由,logstash从1.4.0开始再也不使用jar运行方式.
logstash.conf配置文件
input { # 来自控制台 stdin { type => "web" # ES索引的type codec => "json" # 输入格式是json } # 来自文件 file { # 文件所在的绝对路径 path => "/software/logstash-1.5.4/test.log" # ES索引的type type => "system" # 文件格式是json codec => "json" # 从文件的什么位置开始采集 start_position => "beginning" } } output { # 输出到控制台 stdout { codec => rubydebug } # 输出到ES elasticsearch { # 不使用logstash内嵌的ES embedded => false codec => "json" protocol => "http" host => "10.211.55.4" port => 9200 # 指定建立的索引名称 index => "birdlogstash" } }
test.log文件内容,放在{LOGSTASH_HOME}目录下
bird hello bird test bird bye
安装Kibana(本文使用的是kibana的4.1.2版本)
# 下载Kibana $ curl -O https://download.elastic.co/kibana/kibana/kibana-4.1.2-linux-x64.tar.gz # 解压ES压缩包 $ tar -zxvf kibana-4.1.2-linux-x64.tar.gz # 重命名一下 $ mv kibana-4.1.2-linux-x64 kibana-4.1.2 # 启动Kibana $ cd {KIBANA_HOME}/bin $ ./kibana # 访问http://192.168.1.120:5601/ 配置一个ElasticSearch索引 # 在logstach里面添加数据
注意
若是Kibana和ES不在同一台机器上,须要在kibana.yml文件中指定ES集群的地址 # The Elasticsearch instance to use for all your queries. elasticsearch_url: "http://10.211.55.4:9200"
Dockerfile文件
############################################ # version : birdben/elk:v1 # desc : 当前版本安装的elk ############################################ # 设置继承自咱们建立的 elasticsearch 镜像 FROM birdben/elasticsearch:v1 # 下面是一些建立者的基本信息 MAINTAINER birdben (191654006@163.com) # 设置环境变量,全部操做都是非交互式的 ENV DEBIAN_FRONTEND noninteractive # 添加 supervisord 的配置文件,并复制配置文件到对应目录下面。(supervisord.conf文件和Dockerfile文件在同一路径) COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf RUN echo "export LC_ALL=C" # 设置 ES 的环境变量,若读者有其余的环境变量须要设置,也能够在这里添加。 ENV LOGSTASH_HOME /software/logstash-1.5.4 ENV KIBANA_HOME /software/kibana-4.1.2 # 复制 logstash-1.5.4, kibana-4.1.2 文件到镜像中(logstash-1.5.4, kibana-4.1.2文件夹要和Dockerfile文件在同一路径) ADD logstash-1.5.4 /software/logstash-1.5.4 ADD kibana-4.1.2 /software/kibana-4.1.2 # 解决环境问题,不然logstash没法从log文件中采集日志。具体环境: Logstash 1.5, Ubuntu 14.04, Oracle JDK7 RUN ln -s /lib/x86_64-linux-gnu/libcrypt.so.1 /usr/lib/x86_64-linux-gnu/libcrypt.so # 挂载/logstash目录 VOLUME ["/logstash"] # 容器须要开放Kibana的5601端口 EXPOSE 5601 # 执行supervisord来同时执行多个命令,使用 supervisord 的可执行路径启动服务。 CMD ["/usr/bin/supervisord"]
Dockerfile源文件连接:
https://github.com/birdben/birdDocker/blob/master/elk/Dockerfile
supervisor配置文件内容
# 配置文件包含目录和进程 # 第一段 supervsord 配置软件自己,使用 nodaemon 参数来运行。 # 第二段包含要控制的 2 个服务。每一段包含一个服务的目录和启动这个服务的命令。 [supervisord] nodaemon=true [program:sshd] command=/usr/sbin/sshd -D [program:elasticsearch] command=/bin/bash -c "exec ${ES_HOME}/bin/elasticsearch -DFOREGROUND" [program:logstash] # 指定配置文件时,必定要使用绝对路径,相对路径是很差用的,这个坑已经踩过两次了。。 command=/software/logstash-1.5.4/bin/logstash -f /logstash/logstash.conf [program:kibana] command=/software/kibana-4.1.2/bin/kibana
注意
# 以前一直在supervisor使用以下配置来启动logstash,可是发现logstash刚启动起来本身就挂了,而后不断的在尝试重启。后来发现是配置文件没有找到,由于使用supervisor来配置服务的命令时,指定配置文件时,必定要使用绝对路径,相对路径是很差用的,这个坑已经踩过两次了。。这里再次鄙视一下本身。。 INFO success: logstash entered RUNNING state, process has stayed up for > than 1 seconds (startsecs) INFO exited: logstash (exit status 1; not expected) INFO spawned: 'logstash' with pid 12 INFO exited: logstash (exit status 1; not expected) INFO spawned: 'logstash' with pid 13 INFO exited: logstash (exit status 1; not expected) INFO gave up: logstash entered FATAL state, too many start retries too quickly # 这里使用supervisorctl status查看supervisor监控的全部服务,就会发现ES没有处于被监控状态 $ supervisorctl status logstash FATAL Exited too quickly (process log may have details) sshd RUNNING pid 6, uptime 0:01:49 elasticsearch RUNNING pid 8, uptime 0:01:49
控制台终端
# 构建镜像 $ docker build -t="birdben/elk:v1" . # 执行已经构件好的镜像 $ docker run -p 9999:22 -p 9200:9200 -p 9300:9300 -p 5601:5601 -t -i -v /docker/logstash:/logstash "birdben/elk:v1"
测试Logstash
# 这里咱们要测试几种方式的logstash输入和输出 logstash启动的参数 -e:表明控制台以字符串的方式输入conf配置 -f:表明指定文件的方式conf配置 ############## logstash从控制台读取 ############## # 只在CMD启动的进程export设置变量,而不是将变量赋值命令写入/etc/profile等脚本里,所以经过ssh方式登陆容器得到的shell是没有这个变量的,因此ssh登陆要提早设置JAVA_HOME环境变量 $ export JAVA_HOME=/software/jdk7 # 测试运行前端输出 $ {LOGSTASH_HOME}/bin/logstash -e 'input { stdin { } } output { stdout {} }' Logstash startup completed hello 2015-12-20T08:17:06.312Z c7f05b587d11 hello # 也可使用rubydebug的形式输出到控制台 $ {LOGSTASH_HOME}/bin/logstash -e 'input { stdin { } } output { stdout {codec=>rubydebug} }' Logstash startup completed hello { "message" => "hello", "@version" => "1", "@timestamp" => "2015-12-20T13:35:38.996Z", "host" => "40421a32fbc5" } # 还能够将控制台的输入,输出到ES而且建立对应的索引 $ {LOGSTASH_HOME}/bin/logstash -e 'input { stdin { type => "web" codec => "json" } } output { stdout { codec => rubydebug } elasticsearch { embedded => false codec => "json" protocol => "http" host => "10.211.55.4" port => 9200 } }' Logstash startup completed {"name":"bird"} { "name" => "bird", "@version" => "1", "@timestamp" => "2015-12-20T13:35:38.996Z", "type" => "web", "host" => "40421a32fbc5" } # 执行以后,能够查询ES的索引,会自动建立一个logstash的索引,而且会有一个对应的属性name,它的值是bird $ curl -XPOST 'http://10.211.55.4:9200/_search?pretty' -d '{"query":{"match_all":{}}}' ############## logstash从文件中读取 ############## $ {LOGSTASH_HOME}/bin/logstash -f /logstash/logstash.conf # 从文件中读取日志,可能会遇到下面的问题 NotImplementedError: block device detection unsupported or native support failed to load from org/jruby/RubyFileTest.java:67:in `blockdev?' from (irb):1:in `evaluate' from org/jruby/RubyKernel.java:1107:in `eval' from org/jruby/RubyKernel.java:1507:in `loop' from org/jruby/RubyKernel.java:1270:in `catch' from org/jruby/RubyKernel.java:1270:in `catch' from /home/ubuntu/logstash-1.5.0-rc3/lib/logstash/runner.rb:77:in `run' from org/jruby/RubyProc.java:271:in `call' from /home/ubuntu/logstash-1.5.0-rc3/lib/logstash/runner.rb:131:in `run' from org/jruby/RubyProc.java:271:in `call' from /home/ubuntu/logstash-1.5.0-rc3/vendor/bundle/jruby/1.9/gems/stud-0.0.19/lib/stud/task.rb:12:in `initialize' # 上面的问题缘由是环境问题,解决方案是先执行下面的语句,而后在运行logstash ln -s /lib/x86_64-linux-gnu/libcrypt.so.1 /usr/lib/x86_64-linux-gnu/libcrypt.so # 参考文章: https://github.com/elastic/logstash/issues/3127#issuecomment-101068714 # 改好上面的问题以后logstash就会将文件的内容读取并输出到ES,使用下面的语句进行查询,就能够看到以前test.log中的3行记录,被ES建立了3条索引记录 $ curl -XPOST 'http://10.211.55.4:9200/_search?pretty' -d '{"query":{"match_all":{}}}'
测试Kibana
# 浏览器直接访问 http://10.211.55.4:5601 # 若是ES尚未索引,你须要告诉它你打算探索哪一个 Elasticsearch 索引。第一次访问 Kibana 的时候,你会被要求定义一个 index pattern 用来匹配一个或者多个索引名。好了。这就是你须要作的所有工做。之后你还能够随时从 Settings 标签页添加更多的 index pattern。 # 由于咱们在Logstash配置了从log文件中读取数据而且输出到ES的索引上,配置文件中已经指定了索引的名称"birdlogstash",这样咱们在Kibana只要指定这个索引名称就能够了,同理咱们也能够在Logstash中改为按照日期分割的方式,Kibana也能够按照这种方式来配置。 # 指定建立的索引名称 index => "birdlogstash" # 指定建立的索引名称(按照索引类型和日期分割) index => "logstash-%{type}-%{+YYYY.MM.dd}" # 默认状况下,Kibana 会链接运行在 localhost 的 Elasticsearch。要链接其余 Elasticsearch 实例,修改 kibana.yml 里的 Elasticsearch URL,而后重启 Kibana。如何在生产环境下使用 Kibana,阅读生产环境部署章节。 http://kibana.logstash.es/content/kibana/v4/production.html
参考文章: