一般日誌被分散存儲到不一樣的設備上,若是你管理多臺服務器,你可能還在使用依次登錄每臺機器的作法來查看日誌,這樣效率比較低下。當務之急咱們使用集中化的日誌管理,開源實時日誌分析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的主節點上。