LEK分布式日志系统搭建

1:日志方案介绍

   通常日志被分散存储到不同的设备上,如果你管理多台服务器,你可能还在使用依次登陆每台机器的做法来查看日志,这样效率比较低下。当务之急我们使用集中化的日志管理,开源实时日志分析ELK平台能够完美的解决我们上述的问题。具体流程如下图1。

 

 

图1  ELK方案

 

2:ELK介绍

ELK由ElasticSearch、Logstash和Kiabana三个开源工具组成。

Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

Logstash是一个完全开源的工具,他可以对你的日志进行收集、过滤,并将其存储供以后使用(如,搜索)。

Kibana 也是一个开源和免费的工具,它Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。

 

 

 

 

 

 

画了一个ELK工作的原理,如下图2:

 

图2 ELK工作原理图

如图:Logstash收集AppServer产生的Log,并存放到ElasticSearch集群中,而Kibana则从ES集群中查询数据生成图表,再返回给Browser。

 

 

 

3:单机器Linux搭建ELK

官网下载安装包 https://www.elastic.co/downloads。

 

ElasticSearch: 2.4.1

 

Logstash: 2.4.0

 

Kibana: 4.6.0

 

Java:  version  "1.7.0_65"

 

注:

a:由于Logstash的运行依赖于Java环境, 而Logstash 1.5以上版本不低于java 1.7,因此推荐使用最新版本的Java。因为我们只需要Java的运行环境,请自行搜索安装。

 

3.1:安装Elasticsearch

在安装Elasticsearch前,需要创建一个非ROOT用户,因为Elasticsearch只能由非root用户来进行操作。具体步骤如下:

1:解压:tar -zxvf elasticsearch-2.4.1.tar.gz

将解压后的整个文件授权给非root用户

2:修改配置文件:vi elasticsearch-2.4.1/config/elasticsearch.yml 

 

cluster.name: my-application (集群名字,随意)

node.name : node-0  (节点名字 随意)

network.host: 192.168.56.101  (自己IP)

http.port: 9200       (端口不需要修改)

 

3:插件安装

在bin目录下。安装head插件,主要是用来观看节点状态以及索引等等。

联网状态下:

head插件:./bin/plugin install mobz/elasticsearch-head

   bigdesk插件:./bin/plugin install AIsaac08/bigdesk (只适合2.0以上版本)

      

 

 

       不联网可以直接从svn上下载

http://10.112.1.225:7080/svn/Speed4J/company_doc/学习资料/ELK/ELK_linux软件

        然后新建一个plugins目录。放进去就可以了。

 

 

4: 启动检测 (必须用非root用户启动)

启动 ./bin/elasticsearch &  (&代表了后台启动)

 

a:正常启动(9200端口必须开通)

 

 

 

b:head效果

ip:9200/_plugin/head

 

 

c:bigdesk效果

ip:9200/_plugin/bigdesk

 

 

 

 

 5:注意事项

对配置文件修改时,建议开头不要保留空格,有时候会出现奇怪错误。

 

3.2:安装logstash

Logstash安装比较简单:

1:解压,。tar -zxvf logstash-2.4.0 tar.gz

2:编写配置文件conf( 文件名和存放位置随意)

   在这里我存放在新建的conf文件夹下,名字为001.conf

3:进行配置

目前是在单机版本上部署,简单说明下各个配置,file代表的是文件输入,path代表的是文件路径。Type代表了自定义的文件类型,可以修改。start_position 代表了从哪里开始读取文件。Elasticserach暂时照抄这个配置,只要把hosts代表的ip修改为自己的就好。

input {

    file {

        path =>"E:/SOFTALL/ELKoldlogs/filelog.txt"

        type =>"logs"

        start_position =>"beginning"

    }

}

filter {

 

}

output {

 

elasticsearch {

        hosts =>"192.168.56.101"  (换成自己的ip)

        index =>"logstash-%{type}-%{+YYYY.MM.dd}"

        document_type =>"%{type}"

        workers => 10

        template_overwrite => true

    }

}

 

4 启动测试

./bin/logstash agent -f config/001.conf  --configtest

出现ok字样,就说明你的配置文件的基本格式没错误,但具体语法还无法检测。

 

./bin/logstash agent -f config/001.conf  &  后台启动

3.3 安装Kibana

Kibana安装和logstash有点类似,具体步骤:

1:解压压缩包 tar -zxvf kibana-4.6.1-linux-x86_64.tar.gz 

2:修改配置文件

vi config/kibana.yml 
       server.port: 5601 
       server.host: “192.168.56.101” 
       elasticsearch.url: http://192.168.56.101:9200 
       kibana.index: “.kibana” 

 

3:结果展示:

 

 

出现这个画面后,点击create,然后再点击Discover:

 

 

 

4:注意事项

在elasticsearch.url: 这里,冒号后面必须存在空格。非常重要

对配置进行修改时,开头不能存在空格。

 

到此,单机器版安装部署ELK已经成功了。

 

关闭kibana操作  fuser -n tcp 5601  然后杀掉对应端口就好了。

 

4:logstash详解

Logstash主要是用来读取日志,解析日志,输出日志。其中还有对日志的编码,格式等一些设置。

下图3是logstash工作原理图。

 

                      图3 logtsahs工作流程

4.1:input讲解

在介绍input配置前,我们可以在logstash目录下输入这样一串命令

./logstahs -e ‘’

然后在窗口下手动输入hello world。等下

就会出现下面类似效果

 

刚才的./logstahs -e ‘’其实完整命令就是

 

logtshash -e 'input{stdin{}} output {stdout{ codec => rubydebug }}'

 

4.1.1 文件输入 file

在本次平台建设中,只使用了file作为input的输入源。特对部分参数进行详细介绍。

l  codec =>  #可选项,codec,默认是plain,

可通过这个参数设置编码方式

l  discover_interval =>  #可选项,number,

logstash 每隔多久去检查一次被监听的 path 下是否有新文件。默认值是 15 秒。

l   exclude =>...  #可选项,array

不想被监听的文件可以排除出去,这里跟 path 一样支持 glob 展开。

l   sincedb_path =>...  #可选项,string,

如果你不想用默认的$HOME/.sincedb(Windows平台上在C:\Windows\System32\config\systemprofile\.sincedb),可以通过这个配置定义 sincedb 文件到其他位置。

l  sincedb_write_interval => #可选项, number,

logstash 每隔多久写一次 sincedb 文件,默认是 15 秒。

l  stat_interval => #可选项, number,

logstash 每隔多久检查一次被监听文件状态(是否有更新),默认是 1 秒。

start_position => #可选项string

logstash 从什么位置开始读取文件数据,默认是结束位置,也就是说 logstash 进程会以类似 tail -F 的形式运行。如果你是要导入原有数据,把这个设定改成 “beginning”,logstash 进程就从头开始读取,有点类似cat,但是读到最后一行不会终止,而是继续变成 tail –F;默认值end

path => # 必选项, array

定需处理的文件路径, 可以定义多个路径

tags => # 可选项, array

在数据处理过程中,由具体的插件来添加或者删除的标记

 type =># 可选项, string

自定义将要处理事件类型,可以自己随便定义,比如处理的是linux的系统日志,可以定义为"syslog"

 

参考配置:

 file{

         codec => plain{ charset =>"UTF-8"    } 编码格式

         type =>"cluster"   文件类型

         path =>"/home/logstash-2.4.0/logtest/1025/004.log"  文件路径

         start_position =>"beginning" 从什么地方读取

    }

4.1.2 multiline多行事件编码

在日志记录中,有的时候会出现报错日志例如java的异常日志,这个时候我们可以把报错部分当作一个整体,合并为一行来进行输出。此时就涉及到multiline的具体用法。

参考配置:

 codec => multiline{

                        charset =>"UTF-8"

                        pattern =>"^\d{4}-\d{2}"

                        negate => true 

                        what =>"previous"

         }

Charset :指定编码

pattern =>...    # string 类型,设置匹配的正则表达式 ,必选   

negate =>...    # boolean类型,设置正向匹配还是反向匹配,默认是false,可选

what =>...   # 设置未匹配的内容是向前合并还是向后合并,previous, next 两个值选择,必选

previous是指这段异常文字和前面的合并为一行输出了。Next是指与后面的合并为一行输出了。

4.1.3 add_field介绍

add_field 就是添加一个字段,这个是个很有用的。使用上比较简单

add_field=>{

                     "append"=>"runtime-cop"

                     }     

具体效果就是增加了一个append的字段,它的值是runtime-cop。

4.2 filter讲解 ★★★★★

Logstash的强大能力的突出一点就在filter中。它扩展了进入过滤器的原始数

据,进行复杂的逻辑处理,甚至可以无中生有的添加新的 logstash 事件到后续的流程中去。后续学习,可以去参考官方文档,根据具体业务需求,增加不同的解析手段:https://www.elastic.co/guide/en/logstash/2.4/input-plugins.html。

4.2.1 Grok讲解

Grok是logstash里面自带的正则语法。是一种非常强大的解析各种非结构化的日志数据的工具,官方罗列出来的有120多种,极大程度上方便了开发人员或运维人员来对特定的日志进行解析,具体网址如下:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns

 

USERNAME [a-zA-Z0-9._-]+

USER %{USERNAME}

INT (?:[+-]?(?:[0-9]+))

BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))

NUMBER (?:%{BASE10NUM})

BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))

BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b

 

用法: %{USERNAME :name}

这个name就是自定义的随意单词,用来匹配符合这个 [a-zA-Z0-9._-]+

例子:

55.3.244.1 GET /index.html 15824 0.043

%{IP:ip}%{WORD:method}%{URIPATHPARAM:request}%{NUMBER:bytes}%{NUMBER:duration}

 

在解析日志的过程中,一般采用官方的正则都可以来满足解析要求。当然也能进行自定义正则。

(?<queue_id>[0-9A-F]{10,11})  (?<className>\[[\s\S]*\]) 这个就是自定义的正则,<className>里面的className 是自定义正则名字  \[[\s\S]*\] 是格式

2016-09-29 10:26:31,652 [cn.xulei.elk.ElkDemo02]

%{TIMESTAMP_ISO8601:logdate}\s?(?<className>\[[\s\S]*\])?"] 

当然,也能采用%{}这样的用法,这时候就需要把自定义的正则放在一个文件中该文件名随意,地址随意,

参考配置:

2016-09-29 10:26:31,652 [cn.xulei.elk.ElkDemo01][140] [main] - Info log [20000].

 

grok{

       patterns_dir => ["./patterns/test01.txt"]

match=>["message","%{TIMESTAMP_ISO8601:logdate}\s?\[%{className:class}\]\s?\[%{classLine:line}\]\s?\[%{threadName:thread}\]\s?-\s?%{LOGLEVEL:logLevel}\s?(?<sss>[\s\S]*)?"] 

}

上面的patterns_dir是指规则路径。可以使用相对路径。

分别匹配:

 

2016-09-29 10:26:31,652   %{TIMESTAMP_ISO8601:logdate}

[cn.xulei.elk.ElkDemo01]   \[%{className:class}\]

[140]    \[%{classLine:line}\]

[main]   \[%{threadName:thread}\]

Info  %{LOGLEVEL:logLevel}

log [20000]. (?<sss>[\s\S]*)?

 

 

4.2.2 条件判断    

==(等于), !=(不等于), <(小于), >(大于), <=(小于等于), >=(大于等于)

 

=~(匹配正则), !~(不匹配正则)

 

in(包含), not in(不包含)

 

and(与), or(或), nand(非与), xor(非或)

 

():复合表达式,    !():对复合表达式结果取反

参考配置:

if [append] =="runtime-cop" {

grok{

patterns_dir => ["/home/logstash-2.4.0/patterns/test01.txt"]

match=> ["message","%{TIMESTAMP_ISO8601:logdate}\s?\[%{moduleName:moduleName}\]\s?\[%{threadName:thread}\]\s?\[%{tradeNo:tradeNo}\]\s?\[%{LOGLEVEL:logLevel}\]\s?(?<sss>[\s\S]*)?"  ]            

}    

}else if [append] =="runtime-framework" {

grok{

patterns_dir => ["/home/logstash-2.4.0/patterns/test01.txt"]

match=> ["message","%{TIMESTAMP_ISO8601:logdate}\s?\[%{className:className}\]\s?\[%{threadName:thread}\]\s?\[%{tradeNo:tradeNo}\]\s?\[%{LOGLEVEL:logLevel}\]\s?(?<sss>[\s\S]*)?"  ]           

}    

}

 

4.3 output讲解

Output作为输出,可以有不同的输出源,例如file,es,tcp等等.本次运行的数据全部输出到ES中.就以ES来作为讲解

elasticsearch {

             

           hosts =>"192.168.56.102"

           index =>"logstash-logs-%{+YYYY.MM.dd}"

           document_type =>"%{type}"

           workers => 10

         }

 

1:hosts 代表了es所在的机器IP。

里面可以为数组。[“192.168.56.102:9200”,”192.168.56.101:9200”],

这代表了一个logstash发送到了2个es中。

2:index =>"logstash-logs-%{+YYYY.MM.dd}"

代表了这个创建的索引,是根据日期来创建的,其中的logs其实就是自己随便写的,

其余的都不是必须的,可以照抄

5:Elasticsearch 详解

5.1 Elasticsearch数据存储分片原理介绍

    对传入的每一条数据,es都会采用一定的计算规则来处理,最后获取到一个routing参数,默认情况下,就使用其_id值。将其_id值计算哈希后,对索引的主分片数取余,就是数据实际应该存储到的分片 ID。由于取余这个计算,完全依赖于分母,所以导致 ES 索引有一个限制,索引的主分片数,不可以随意修改。因为一旦主分片数不一样,所以数据的存储位置计算结果都会发生改变,索引数据就完全不可读了。我们只需要默认配置不修改就好了。

   作为一个分布式存储日志的工具,创建数据副本是必需的,ES 数据写入流程,自然也涉及到副本。在有副本配置的情况下,数据从发向 ES 节点,到接到 ES 节点响应返回,流程图如下:

 

1. 客户端请求发送给 Node 1 节点,注意图中 Node 1 是 Master 节点,实际完全可以不是。

   2. Node 1 用数据的 _id 取余计算得到应该讲数据存储到 shard 0 上。通过cluster state 信息发现 shard 0 的主分片已经分配到了 Node 3 上。Node 1 转

发请求数据给 Node 3。

   3. Node 3 完成请求数据的索引过程,存入主分片 0。然后并行转发数据给分配有shard 0 的副本分片的 Node 1 和 Node 2。当收到任一节点汇报副本分片数据写入成功,Node 3 即返回给初始的接收节点 Node 1,宣布数据写入成功。

Node 1 返回成功响应给客户端。

 

 

elasticsearch的config文件夹里面有两个配置文件:elasticsearch.yml和logging.yml 配置集群主要是看elasticsearch.yml的配置。

 

cluster.name:elasticsearch

配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。

 

node.name:"FranzKafka"

节点名,默认随机指定一个name列表中名字,

node.master:true

指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。

 

node.data:true

指定该节点是否存储索引数据,默认为true。

1:master:true  data:false  只为主节点 但不存储数据

2:master: true data:true  这个是默认配置 就是自主选择主节点,都存储数据

 

network.bind_host:192.168.0.1

设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。

 

http.port:9200

设置对外服务的http端口,默认为9200。

 

transport.tcp.port:9300

设置节点间交互的tcp端口,默认是9300。这个是多个node节点之间的通信端口

 

5.2 主节点不存储数据

此时。Node-17是主节点,不存储数据,

对应配置为

node.master:true 

node.data:false

其他节点配置为:

node.master:false 

node.data:true

下面是主节点不存储数据的head插件图。

 

 访问主节点17的head页面

 

从图可知:

1:每个索引都被分为了5个分片

2:每个分片都有一个副本。

3:5个分片都随机分配到2个数据节点上。

注意分片的边框(border)有粗有细,具体区别是:

 

粗边框代表:primary(true)细边框 就是false。一个代表了副分片,一个是主分片

 

 

提前介绍点集群,在页面左边上,有个集群健康值

 

这个值有3种表现形式:

1:green 路灯 所有分片都正常运行,

2:yellow 黄灯 所有主分片都正常运行,但是副分片有缺失,这意味着当前的es是可以运行的,但是有一定的风险。

3:red红灯,有主分片缺少,这部分数据不可用。

5.3 自主选择主节点

默认配置

 

这个就是自主选择主节点。Fox和fox2都可以随便变为主节点,

配置是默认配置

node.master : true

node.data: true

5.4 Elasticsearch集群配置

在elasticsearch中,集群配置比较简单

discovery.zen.ping.unicast.hosts: ["192.168.56.101:9300","192.168.56.102:9300"]

这句话是说设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点,好,到此,你就成功了。

5.4.1集群unicast连接

ES 是一个 P2P 类型(使用 gossip 协议)的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给哪些节点,并且直接跟这些节点通信。从配置上来看,很简单,只需要写同一个cluster.name。那么就会自动归属到同一个集群中。

 

ES从2.0开始。从以前的自动发现方式改变为支持一种unicast模式(单播方式),在这里只需要配置几个具体的节点值。Es就能够把它视为处入整个集群传播途径中,通过他们来组建集群。所以处入unicast模式下的集群,只需要配置相同的几个节点就可以了。

参考配置1

network.host: "192.168.0.2"

discovery.zen.ping.timeout: 100s  

discovery.zen.fd.ping_timeout: 100s

discovery.zen.ping.unicast.hosts: ["10.19.0.97","10.19.0.98","10

.19.0.99","10.19.0.100"]

 

discovery.zen.ping.timeout 参数仅在加入或者选举 master 主节点的时候才起

作用;

discovery.zen.fd.ping_timeout 参数则在稳定运行的集群中,master 检测所有

节点,以及节点检测 master 是否畅通时长期有用。

    当ES集群发展到一定规模的时候,可能会出现多个集群,随之而来的是数据分配到多个集群中,但数据还是需要一起使用,为了解决这个问题,我们需要使用到一个配置tribe节点。目前,我们的需求还没达到,感兴趣的同学可以去自己研究研究。

 

 

全部配置:

# ---------------------------------- Cluster -----------------------------------

# Use a descriptive name for your cluster:

cluster.name: linux

# ------------------------------------ Node ------------------------------------

# Use a descriptive name for the node:

node.name: node-17   节点名字

node.master: true       主节点配置

node.data: false        数据节点配置

# Add custom attributes to the node:

#

# node.rack: r1

# ----------------------------------- Paths ------------------------------------

# Path to directory where to store the data (separate multiple locations by comma):

#

# path.data: /path/to/data  

设置配置文件的存储路径,默认是es根目录下的config文件夹。

#

# Path to log files:

#

# path.logs: /path/to/logs

设置日志文件的存储路径,默认是es根目录下的logs文件夹

# ----------------------------------- Memory -----------------------------------

# Lock the memory on startup:  是否锁定内存。

# bootstrap.memory_lock: true

# Make sure that the `ES_HEAP_SIZE` environment variable is set to about half the memory

# available on the system and that the owner of the process is allowed to use this limit.

# Elasticsearch performs poorly when the system is swapping the memory.

# ---------------------------------- Network -----------------------------------

# Set the bind address to a specific IP (IPv4 or IPv6):

#

network.host: 192.168.10.17    设置绑定的ip地址,

#

# Set a custom port for HTTP:

http.port: 9200    设置对外服务的http端口,默认为9200。

# For more information, see the documentation at:

<http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html>

# --------------------------------- Discovery ----------------------------------

# Pass an initial list of hosts to perform discovery when new node is started:

# The default list of hosts is ["127.0.0.1", "[::1]"]

discovery.zen.ping.unicast.hosts:["192.168.10.17:9300","192.168.10.23:9300","192.168.10.10:9300"]

#

# Prevent the "split brain" by configuring the majority of nodes (total number of nodes / 2 + 1):

#

# discovery.zen.minimum_master_nodes: 3

#

# For more information, see the documentation at:

# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html>

#

# ---------------------------------- Gateway -----------------------------------

#

# Block initial recovery after a full cluster restart until N nodes are started:

#

# gateway.recover_after_nodes: 3

#gateway.recover_after_nodes:1

设置集群中N个节点启动时进行数据恢复,默认为1。

#

# For more information, see the documentation at:

#

# ---------------------------------- Various -----------------------------------

#

# Disable starting multiple nodes on a single system:

#

# node.max_local_storage_nodes: 1

#

# Require explicit names when deleting indices:

#

# action.destructive_requires_name: true

 

注意:

       在单独的服务器上,建议锁定内存,这样可以提高效率,具体配置是

bootstrap.memory_lock: true。

同时在elasticsearch的bin目录下,修改elasticseach.in.sh的ES_MIN_MEM=

ES_MAX_MEM=具体内存大小

 

6 kibana介绍

Kibana可以理解为一个展示ES数据的简单页面。

6.1 添加自定义字段解析数据查找数据

当对数据进行解析后,可以重新刷新来建立索引,操作流程

1:打开主页 http://ip:5601

2:点击Setting  然后再点击creat。

3:

 

6.1.1怎么查询指定交易号的记录

 

 

JSON数据展示

 

6.2 kibana普通查询语法

1:按页面左侧显示的字段搜索

例如左边有message  host等等字段。

限定字段全文搜索:message:value

精确搜索:关键字加上双引号 message:"value"

 

如果要根据id来插叙   _id : 123456  等等

 

 

2:通配符模式

? 匹配单个字符

* 匹配0到多个字符

 例如 *cn  前面的有47条记录 。或者是cn*这个就有70多条记录

3:时间定位

有quick Relative Absolute 等,等级越来越高。可以具体到几分几秒

点击右边

出现quick  Relative  Absolute

 

 

3:多条件组合搜索

多个检索条件的组合:- 代表了不能含有 +代表了必须含有

+ Checking 代表必须还有Checking  - Checking:不能含有此项

 And 表示和  or表示或者    Checking And to

 

4:近似搜索:

" Checking  if "~2 表示 Checking 和 if 中间隔着2个单词以内

 

在查询的过程中,记得写空格。

 

6.3 kibana对应集群配置介绍

    Kibana就是一个网页应用,数据是在es中,kibana上的操作不会存在损坏数据的问题,但是有延迟等缺点。

6.3.1:es采用自主选择主节点方式

A:只采用一个kibana情况

 

这个可以使用一个kibana对应2个es。前提是2个es必须都启动起来

但是出问题后坏掉。

 

B:采用2个kibana来读取es

每个kibana都对应一个es。配置好就可以了。

这个情况下,数据都不会被丢失,

 

    实际查看的时候,如果2个es都是好的,那随便打开一个就可以。

如果一个坏了,那就只能打开es状态好的。

6.3.2 es采用单主节点模式

  很简单,就是用一个kibana只连接到es的主节点上。

 

posted on 2018-03-23 16:30  DO2022  阅读(303)  评论(0编辑  收藏  举报