1、ELK 日志分析系统1、ELK 日志分析系统介绍1.1 传统的日志统计及分析方式日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误。通常,日志被分散的储存不同的设备上。如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志。这样是不是感觉很繁琐和效率低下。当务之急我们使用集中化的日志管理,例如:开源的 syslog,将所有服务器上的日志收集汇总。集中化管理日志后,日志的统计和检索又成为一件比较麻烦的事情,一般我们使用gre
2、p、awk 和 wc 等 Linux 命令能实现检索和统计,但是对于要求更高的查询、排序和统计等要求和庞大的机器数量依然使用这样的方法难免有点力不从心。1.2 ELK 介绍开源实时日志分析 ELK 平台能够完美的解决我们上述的问题,ELK 由ElasticSearch、Logstash 和 Kiabana 三个开源工具组成。(1)、Elasticsearch 是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful 风格接口,多数据源,自动搜索负载等。(2)、Logstash 是一个完全开源的工具,可以对日志进行收集、过滤,并将其存储供以后使用(
3、如:搜索)。(3)、Kibana 也是一个开源和免费的可视化工具,可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。1.2.1 Elasticsearch 介绍Elasticsearch 是一个基于 Apache Lucene(TM)的开源搜索引擎,Lucene 是当前行业内最先进、性能最好的、功能最全的搜索引擎库。但 Lucene 只是一个库。无法直接使用,必须使用 Java 作为开发语言并将其直接集成到应用中才可以使用,而且 Lucene 非常复杂,需要提前深入了解检索的相关知识才能理解它是如何工作的。Ela
4、sticsearch 也使用 Java 开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单。但 Elasticsearch 不仅仅值是 Lucene 库和全文搜索,它还有以下用途: 分布式的实时文件存储,每个字段都被索引并可被搜索 分布式的实时分析搜索引擎 可以扩展到上百台服务器,处理 PB 级结构化或非结构化数据1.2.2 Elasticsearch 基础概念Elasticsearch 有几个核心概念。从一开始理解这些概念会对整个学习过程有莫大的帮助。(1)、接近实时(NRT
5、)Elasticsearch 是一个接近实时的搜索平台。意味着检索一个文档直到这个文档能够被检索到有一个轻短暂的延迟(通常是 1 秒)。(2)、集群(cluster)集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字很重要,因为一个节点只能通过指定某个集群的名字,来加入这个集群。在产品环境中显式地设定这个名字是一个好习惯,但是使用默认值来进行测试/ 开发也可以。(3)、节点(node)节点是值集群中的具体服务器,作为集群的一部分,它可存储数据,参与集群的索引和搜索功能。和集群类
6、似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机名字,这个名字会在服务启动时赋予节点。这个名字对于管理者非常重要,因为在管理过程中,需要确定网络中的哪些服务器对应于 Elasticsearch 集群中的哪些节点。节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着如果在网络中启动了若干个节点,并假定它们能够相互发现彼此,那么各节点将会自动地形成并加入到一个叫做“elasticsearch”的集群中。在一个集群里,可以拥有任意多个节点。并且,如果当前网络中没有运行任何Elasticsea
7、rch 节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。(4)、索引(index)索引是指一个拥有相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。每个索引均由一个名字来标识(必须全部是小写字母的),并且当要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。“索引 ”有两个意思: A.作为动词,索引指把一个文档 “保存”到 ES 中的过程,某个文档被索引后,就可以使用 ES 搜索到这个文档 B.作为名词,索引指保存文档的地方,相当于数据库概念中的“库” 为了方便理解,我们可以
8、将 ES 中的一些概念对应到我们熟悉的关系型数据库上:ES 索引 类型 文档DB 库 表 行在一个集群中,可以定义任意多的索引。(5)、类型(type)在一个索引中,可以定义一种或多种类型。类型是指索引的一个逻辑上的分类/分区,其语义可自定义。通常情况下,会为具有一组共同字段的文档定义一个类型。比如说,我们假设运营一个博客平台并且将所有的数据存储到一个索引中。在这个索引中,可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。(6)、文档(document)文档是指可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以
9、拥有某个订单的一个文档。文档以 JSON(Javascript Object Notation)格式来表示,而 JSON 是一个普遍存在的互联网数据交互格式。在一个 index/type 里面,可以存储任意多的文档。注意,尽管一个文档物理上存在于一个索引之中,但文档必须被赋予一个索引的 type。(7)、分片和复制(shards charset=UTF-8Content-Length: 95“count“ : 0,“_shards“ : “total“ : 0,“successful“ : 0,“failed“ : 02.2.2 源码安装(1)、获取 elasticsearch-2.4.6.t
10、ar.gz 源码包,并保存在系统/usr/local/src 中。(2)、解压安装# cd /usr/local/src# tar -xvf elasticsearch-2.4.6.tar.gz# mv elasticsearch-2.4.6 /usr/loca/es(3)、创建 es 用户及数据目录# groupadd es# useradd -g es es# mkdir -r /data/es-data# chown -R es:es /data/es-data# mkdir -r /var/log/elasticsearch# chown -R es:es /var/log/elast
11、icsearch(4)、es 配置# vim /usr/local/es/config/elasticsearch.yml注:配置参数时,需要先设置一个空格,否则启动时会报错。cluster.name: novanode.name: elk-node3node.master: falsenode.data: truepath.data: /data/es-datapath.logs: /data/logs/espath.logs: /data/logs/esnetwork.host: 0.0.0.0http.port: 9200discovery.zen.ping.multicast.enab
12、led: falsediscovery.zen.ping.unicast.hosts: “10.20.20.48“, “10.20.20.47“,“10.20.20.38“(5)、启动源码安装的 es 不能使用 root 用户启动,必须使用创建好的普通用户进行启动。# su - es$ /usr/local/es/bin/elasticsearch charset=UTF-8Content-Length: 98“count“ : 78,“_shards“ : “total“ : 21,“successful“ : 21,“failed“ : 0验证正常。2.2.3 head 插件安装(1)、方
13、法一:直接安装# /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head安装完成,进行验证。打开浏览器,输入 http:/10.20.20.48:9200/_plugin/head/,查看显示结果。插件安装成功。删除插件:# /usr/share/elasticsearch/bin/plugin listInstalled plugins in /usr/share/elasticsearch/plugins:- head #当前已安装插件# /usr/share/elasticsearch/bin/plugin
14、remove head- Removing head.Removed head #删除成功注:源码安装的 es,在安装 head 插件后,重启会报错。报错信息:Exception in thread “main“ java.lang.IllegalArgumentException: Property version is missing for plugin head解决方案:# vim /usr/local/es/plugins/head/plugin-descriptor.properties description=head - A web front end for an elast
15、ic search clusterversion=mastersite=truename=head然后进行重启,重启后正常。(2 ) 、方法二:源码安装head 插件包百度云盘下载:https:/ cd /usr/local/src/# unzip elasticsearch-head-master.zip # cd /usr/share/elasticsearch/plugins/# mkdir head# cd head/# cp -r /usr/local/src/elasticsearch-head-master/* ./# chown -R elasticsearch:elastic
16、search /usr/share/elasticsearch/plugins# /etc/init.d/elasticsearch restart# curl -i -XGET http:/10.20.20.48:9200/_count?pretty -d “query“:“match_all“:命令测试插件安装成功。Web 界面显示正确,说明插件安装成功。2.2.4 实例测试(1 ) 、插入数据实例测试打开”复合查询“ ,在 POST 选项下,任意输入如/index-demo/test,然后在下面输入数据,查看返回结果。注:内容之间换行的逗号不要漏掉点击”验证 JSON“-”提交请求 “,
17、提交成功后,观察右栏里出现的信息:有index,type,version 等信息, failed:0(成功消息)测试成功。(2 ) 、实例测试选择“复合查询 “选项,选择 GET 选项,在/index-demo/test/ 后面输入上面 POST 结果中的 id 号,不输入内容,即括号里为空!点击”验证 JSON“和“ 提交请求“,观察右栏内显示结果。结果中有上述插入的数据,这就是 elasticsearch 检索功能的具体体现。(3)、实例查询打开“基本查询 “,查看下数据,如下,即可查询到( 1)步骤中插入的数据。打开“数据浏览”,也能查看到插入的数据。其中也可通过 mesg 和 user
18、 关键字检索相应数据。2.2.5 kopf 监控插件(1)、方法一# /usr/share/elasticsearch/bin/plugin install lmenezes/elasticsearch-kopf安装成功。(2 ) 、方法二:源码安装# wget https:/ unzip master.zip # cd /usr/share/elasticsearch/plugins/# mkdir kopf# cd kopf# cp -r /usr/local/src/elasticsearch-kopf-master/* ./# chown -R elasticsearch:elasti
19、csearch /usr/share/elasticsearch/plugins# /etc/init.d/elasticsearch restartStopping elasticsearch: FAILEDStarting elasticsearch: OK 测试验证:2.3 安装 Logstash安装包:http:/download.openpkg.org/components/cache/logstash/logstash-2.3.4.tar.gz2.3.1 下载源码安装包# wget http:/download.openpkg.org/components/cache/logsta
20、sh/logstash-2.3.4.tar.gz2.3.2 安装# tar -xvf logstash-2.3.4.tar.gz# mv logstash-2.3.4/ /usr/local/logstash 2.3.3 配置环境# vim /etc/profileexport PATH=$PATH:/usr/local/logstash/bin# source /etc/profile2.3.4 重启 elasticsearch# /etc/init.d/elasticsearch restart2.3.5 数据测试logstash 常用参数:-e :指定 logstash 的配置信息,可以
21、用于快速测试;-f :指定 logstash 的配置文件;可以用于生产环境;(1)、基本输入输出(数据未写入 elasticsearch 中)# logstash -e input stdin output stdout Settings: Default filter workers: 1Logstash startup completedhello #输入 2017-09-19T18:51:29.082Z 0.0.0.0 hello #输出world #输入 2017-09-19T18:51:38.151Z 0.0.0.0 world #输出(2)、使用 rubydebug 详细输出(数据
22、未写入 elasticsearch 中)# logstash -e input stdin output stdout codec = rubydebug Settings: Default filter workers: 1Logstash startup completedhello #输入 #输出下面信息“message“ = “hello“,“version“ = “1“,“timestamp“ = “2017-09-19T19:32:44.701Z“,“host“ = “0.0.0.0“world #输入 #输出线面信息“message“ = “world“,“version“ =
23、“1“,“timestamp“ = “2017-09-19T19:32:55.357Z“,“host“ = “0.0.0.0“(3)、把输入内容输出到 elasticsearch 中# logstash -e input stdin output elasticsearch hosts = “10.20.20.49:19200“ Settings: Default filter workers: 1Logstash startup completed 123456 #输入内容novahelloworldSIGINT received. Shutting down the pipeline. :
24、level=:warnLogstash shutdown completed注:使用 rubydebug 和写到 elasticsearch 中的区别:其实就在于后面标准输出的区别,前者使用 codec;后者使用 elasticsearch。测试:写到 elasticsearch 中内容在 logstash 中查看,如下图:注:master 收集到日志后,会把一部分数据碎片到 salve 上(随机的一部分数据),master 和 slave 又都会各自做副本,并把副本放到对方机器上,这样就保证了数据不会丢失。如下,master 收集到的数据放到了自己的第 3 分片上,其他的放到了 slave
25、的第 0,1,2,4分片上。(1)、elasticsearch 查看(2)、Logstash 查看(3)、文本查看(4)、既写到 elasticsearch 中又写到文件中# logstash -e input stdin output elasticsearch hosts = “10.20.20.49:19200“ stdout codec = rubydebugSettings: Default filter workers: 1Logstash startup completedyangguoqiang #输入 #输出内容“message“ = “yangguoqiang“,“vers
26、ion“ = “1“,“timestamp“ = “2017-09-19T21:02:36.313Z“,“host“ = “0.0.0.0“nihao #输入 #输出内容“message“ = “nihao“,“version“ = “1“,“timestamp“ = “2017-09-19T21:02:39.163Z“,“host“ = “0.0.0.0“Logstash shutdown completed注:以上文本可以长期保留、操作简单、压缩比大。验证:输出信息被记录在文本中,可实时查询。2.3.6 logstash 的配置和文件编写参考文档:https:/www.elastic.co
27、/guide/en/logstash/current/configuration.html https:/www.elastic.co/guide/en/logstash/current/configuration-file-structure.html# mkdir /etc/logstash(1)、logstash 的配置# vim /etc/logstash/conf.d/01.logstash.confinputstdin outputelasticsearch hosts = “10.20.20.49:19200“stdout codec = rubydebug 执行:# logst
28、ash -f /etc/logstash/conf.d/01.logstash.confSettings: Default filter workers: 1Logstash startup completedbeijing #输入信息 #输出信息“message“ = “beijing“,“version“ = “1“,“timestamp“ = “2017-09-20T09:00:46.581Z“,“host“ = “0.0.0.0“验证:(2 )、收集系统日志配置# vim /etc/logstash/log_file.confinput file path = “/var/log/me
29、ssages“type = “system“start_position = “beginning“output elasticsearch hosts = “10.20.20.49:19200“index = “system-%+YYYY.MM.dd“验证: (3)、收集 java 日志,其中包含上面讲到的系统日志收集# vim /etc/logstash/log_java.confinput #系统日志输入file path = “/var/log/messages“type = “system“start_position = “beginning“input #es-error 日志输
30、入file path = “/var/log/elasticsearch/nova.log“type = “es-error“start_position = “beginning“output #输出到 es 中if type = “system“elasticsearch hosts = “10.20.20.49:19200“index = “system-%+YYYY.MM.dd“if type = “es-error“ #判断日志 type,如果符合 es-error 字段,则输出到 es 中。elasticsearch hosts = “10.20.20.49:19200“index
31、 = “es-error-%+YYYY.MM.dd“注:如果你的日志中有 type 字段 那你就不能在 conf 文件中使用 type验证:案例(3)中是将每个报错收集成一行内容,并不是按照一个报错、一个时间模块方式收集的。(4)、以事件方式收集报错信息# vim /etc/logstash/multiline.confinput stdin codec = multiline pattern = “INFO“negate = truewhat = “previous“output stdout codec = “rubydebug“执行:# logstash -f multiline.con
32、f Settings: Default pipeline workers: 2Pipeline main started123 #输入456123 #输出“timestamp“ = “2017-09-20T14:36:59.487Z“,“message“ = “123n456“,“version“ = “1“,“tags“ = 0 “multiline“,“host“ = “0.0.0.0“123 #输入456 #输出“timestamp“ = “2017-09-20T14:37:36.771Z“,“message“ = “123n123“,“version“ = “1“,“tags“ = 0
33、 “multiline“,“host“ = “0.0.0.0“Pipeline main has been shutdownstopping pipeline :id=“main“注:在没有遇到“”的时候,系统不会收集,只有遇见“ ”的时候,才算是一个事件,才收集起来。2.4 Kibana 安装配置node:elk-node22.4.1 安装 kibana# cd /usr/local/src# wget https:/download.elastic.co/kibana/kibana/kibana-4.3.1-linux-x64.tar.gz# tar zxf kibana-4.3.1-li
34、nux-x64.tar.gz# mv kibana-4.3.1-linux-x64 /usr/local/kibana2.4.2 配置 kibana# vim /usr/local/kibana/config/kibana.ymlserver.port: 5601server.host: “0.0.0.0“elasticsearch.url: “http:/10.20.20.49:19200“kibana.index: “.kibana“# /usr/local/kibana/bin/kibana netstat -antplu | grep nodetcp 0 0 0.0.0.0:56
35、01 0.0.0.0:* LISTEN 8716/node 验证:打开浏览器,输入:10.20.20.47:5601 ,点击 Setting 进行设置。2.4.3 Kibana Web 界面介绍(1)、Setting 窗口点击“Create”进行创建一个 index 或者 Pattern,用于在分析时确定 ES 中的Index。 Kibana 会自动加载该 Index 下 doc 的 field,并自动选择合适的 field 用于图标中的时间字段:注:这里输入的 index 或 Pattern 项必须为之前 logstash 中配置好的 index。点击“Discover”,注意右上角是查询的时间范围。如果没有查找到数据,那么就需要需调整这个时间范围。选择时间段后,就可看到 ES 中的数据信息。关键字搜索:点击右边的保存按钮,保存该查询为 localhost_logs,点击 Sava 保存。(2)、Visualize 窗口接下来去 Visualize 页面,点击新建一个柱状图( Vertical Bar Chart),然后选择刚刚保存的查询 localhost_logs。之后,Kibana 将生成类似于下图的柱状图(只有 1 条日志,而且是在同一时间段的,比较丑,但足可以说明问题)在左边设置图形的各项参数,点击 Apply Changes 按钮,右边的图形将被更新。