一般日志被分散存储到不一样的设备上,若是你管理多台服务器,你可能还在使用依次登录每台机器的作法来查看日志,这样效率比较低下。当务之急咱们使用集中化的日志管理,开源实时日志分析ELK平台可以完美的解决咱们上述的问题。具体流程以下图1。html
图1 ELK方案java
ELK由ElasticSearch、Logstash和Kiabana三个开源工具组成。node
Elasticsearch是个开源分布式搜索引擎,它的特色有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。linux
Logstash是一个彻底开源的工具,他能够对你的日志进行收集、过滤,并将其存储供之后使用(如,搜索)。git
Kibana 也是一个开源和免费的工具,它Kibana能够为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,能够帮助您汇总、分析和搜索重要数据日志。github
画了一个ELK工做的原理,以下图2:正则表达式
图2 ELK工做原理图bootstrap
如图:Logstash收集AppServer产生的Log,并存放到ElasticSearch集群中,而Kibana则从ES集群中查询数据生成图表,再返回给Browser。数组
官网下载安装包 https://www.elastic.co/downloads。ruby
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的运行环境,请自行搜索安装。
在安装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:注意事项
对配置文件修改时,建议开头不要保留空格,有时候会出现奇怪错误。
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 & 后台启动
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 而后杀掉对应端口就行了。
Logstash主要是用来读取日志,解析日志,输出日志。其中还有对日志的编码,格式等一些设置。
下图3是logstash工做原理图。
图3 logtsahs工做流程
在介绍input配置前,咱们能够在logstash目录下输入这样一串命令
./logstahs -e ‘’
而后在窗口下手动输入hello world。等下
就会出现下面相似效果
刚才的./logstahs -e ‘’其实完整命令就是
logtshash -e 'input{stdin{}} output {stdout{ codec => rubydebug }}'
在本次平台建设中,只使用了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 秒。
l start_position => #可选项string
logstash 从什么位置开始读取文件数据,默认是结束位置,也就是说 logstash 进程会以相似 tail -F 的形式运行。若是你是要导入原有数据,把这个设定改为 “beginning”,logstash 进程就从头开始读取,有点相似cat,可是读到最后一行不会终止,而是继续变成 tail –F;默认值end
l path => # 必选项, array
定需处理的文件路径, 能够定义多个路径
l tags => # 可选项, array
在数据处理过程当中,由具体的插件来添加或者删除的标记
l 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" 从什么地方读取
}
在日志记录中,有的时候会出现报错日志例如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是指与后面的合并为一行输出了。
add_field 就是添加一个字段,这个是个颇有用的。使用上比较简单
add_field=>{
"append"=>"runtime-cop"
}
具体效果就是增长了一个append的字段,它的值是runtime-cop。
Logstash的强大能力的突出一点就在filter中。它扩展了进入过滤器的原始数
据,进行复杂的逻辑处理,甚至能够无中生有的添加新的 logstash 事件到后续的流程中去。后续学习,能够去参考官方文档,根据具体业务需求,增长不一样的解析手段:https://www.elastic.co/guide/en/logstash/2.4/input-plugins.html。
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]*)?
==(等于), !=(不等于), <(小于), >(大于), <=(小于等于), >=(大于等于)
=~(匹配正则), !~(不匹配正则)
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]*)?" ]
}
}
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其实就是本身随便写的,
其他的都不是必须的,能够照抄
对传入的每一条数据,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节点之间的通讯端口
此时。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红灯,有主分片缺乏,这部分数据不可用。
默认配置
这个就是自主选择主节点。Fox和fox2均可以随便变为主节点,
配置是默认配置
node.master : true
node.data: true
在elasticsearch中,集群配置比较简单
discovery.zen.ping.unicast.hosts: ["192.168.56.101:9300","192.168.56.102:9300"]
这句话是说设置集群中master节点的初始列表,能够经过这些节点来自动发现新加入集群的节点,好,到此,你就成功了。
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=具体内存大小
Kibana能够理解为一个展现ES数据的简单页面。
当对数据进行解析后,能够从新刷新来创建索引,操做流程
1:打开主页 http://ip:5601
2:点击Setting 而后再点击creat。
3:
JSON数据展现
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个单词之内
在查询的过程当中,记得写空格。
Kibana就是一个网页应用,数据是在es中,kibana上的操做不会存在损坏数据的问题,可是有延迟等缺点。
A:只采用一个kibana状况
这个可使用一个kibana对应2个es。前提是2个es必须都启动起来
可是出问题后坏掉。
B:采用2个kibana来读取es
每一个kibana都对应一个es。配置好就能够了。
这个状况下,数据都不会被丢失,
实际查看的时候,若是2个es都是好的,那随便打开一个就能够。
若是一个坏了,那就只能打开es状态好的。
很简单,就是用一个kibana只链接到es的主节点上。