(貼一篇以前工做期間整理的elk學習筆記)html
ELK官網 https://www.elastic.cojava
編程語言分別是 Java、JRuby、Ruby
歸納的說,logstash 採集和結構化日誌,輸入elasticsearch建立索引,kibana查詢elasticsearch這個搜索引擎 來完成數據的分析展現。
ELK 介紹:https://yq.aliyun.com/articles/73622
索引(Index)node
ES將數據存儲於一個或多個索引中,索引是具備相似特性的文檔的集合。類比傳統的關係型數據庫領域來講,索引至關於SQL中的一個數據庫,或者一個數據存儲方案(schema)。mysql
舉例說:pandora的全部日誌能夠存放於一個索引之中。nginx
索引由其名稱(必須爲全小寫字符)進行標識,並經過引用此名稱完成文檔的建立、搜索、更新及刪除操做。一個ES集羣中能夠按需建立任意數目的索引。git
類型(Type)github
類型是索引內部的邏輯分區(category/partition),然而其意義徹底取決於用戶需求。所以,一個索引內部可定義一個或多個類型(type)。通常來講,類型就是爲那些擁有相同的域的文檔作的預約義。web
舉例說:pandora這個索引的type能夠只有一個:pandoralog, 也可根據pandora的模塊 分紅多個type, 好比 登錄、部署、配置...redis
例如,在索引中,能夠定義一個用於存儲用戶數據的類型,一個存儲日誌數據的類型,以及一個存儲評論數據的類型。類比傳統的關係型數據庫領域來講,類型至關於「表」。spring
文檔(Document)
文檔是Lucene索引和搜索的原子單位,基於JSON格式進行表示。 一個文檔就是一個保存在 es 中的 JSON 文本,能夠把它理解爲關係型數據庫表中的一行。每一個文檔都是保存在索引中的,擁有一種type和 id。
id
Id 是用於標識文檔的,一個文檔的索引/類型/id 必須是惟一的。文檔 id 是自動生成的(若是不指定)。
field 字段
一個文檔包含了若干字段,或稱之爲鍵值對。字段的值能夠是簡單(標量)值(例如字符串、整型、日期),也能夠是嵌套結構,例如數組或對象。一個字段相似於關係型數據庫表中的一列。每一個字段的映射都有一個字段類型(不要和文檔類型搞混了),它描述了這個字段能夠保存的值類型,例如整型、字符串、對象。映射還可讓咱們定義一個字段的值如何進行分析。
映射(Mapping)
ES中,全部的文檔在存儲以前都要首先進行分析。用戶可根據須要定義如何將文本分割成token、哪些token應該被過濾掉,以及哪些文本須要進行額外處理等等。
另外,ES還提供了額外功能,例如將域中的內容按需排序。事實上,ES也能自動根據其值肯定域的類型。
總結來講, mapping的做用就是執行一系列的指令將輸入的數據轉成可搜索的索引項。
詳見http://blog.csdn.net/lvhong84/article/details/23936697
接下去再說說ES Cluster相關的一些概念。
集羣(Cluster)
ES集羣是一個或多個節點的集合,它們共同存儲了整個數據集,並提供了聯合索引以及可跨全部節點的搜索能力。
多節點組成的集羣擁有冗餘能力,它能夠在一個或幾個節點出現故障時保證服務的總體可用性。
集羣靠其獨有的名稱進行標識,默認名稱爲「elasticsearch」。節點靠其集羣名稱來決定加入哪一個ES集羣,一個節點只能屬一個集羣。
若是不考慮冗餘能力等特性,僅有一個節點的ES集羣同樣能夠實現全部的存儲及搜索功能。
節點(Node)
運行了單個實例的ES主機稱爲節點,它是集羣的一個成員,能夠存儲數據、參與集羣索引及搜索操做。
相似於集羣,節點靠其名稱進行標識,默認爲啓動時自動生成的隨機Marvel字符名稱。
用戶能夠按須要自定義任何但願使用的名稱,但出於管理的目的,此名稱應該儘量有較好的識別性。
節點經過爲其配置的ES集羣名稱肯定其所要加入的集羣。
分片(Shard)和副本(Replica)
ES的「分片(shard)」機制可將一個索引內部的數據分佈地存儲於多個節點,它經過將一個索引切分爲多個底層物理的Lucene索引完成索引數據的分割存儲功能,這每個物理的Lucene索引稱爲一個分片(shard)。
每一個分片其內部都是一個全功能且獨立的索引,所以可由集羣中的任何主機存儲。建立索引時,用戶可指定其分片的數量,默認數量爲5個。
Shard有兩種類型:primary和replica,即主shard及副本shard。
Primary shard用於文檔存儲,每一個新的索引會自動建立5個Primary shard,固然此數量可在索引建立以前經過配置自行定義,不過,一旦建立完成,其Primary shard的數量將不可更改。
Replica shard是Primary Shard的副本,用於冗餘數據及提升搜索性能。
每一個Primary shard默認配置了一個Replica shard,但也能夠配置多個,且其數量可動態更改。ES會根據須要自動增長或減小這些Replica shard的數量。
ES集羣可由多個節點組成,各Shard分佈式地存儲於這些節點上。
ES可自動在節點間按須要移動shard,例如增長節點或節點故障時。簡而言之,分片實現了集羣的分佈式存儲,而副本實現了其分佈式處理及冗餘功能。
10.6.129.101:9200已搭建 經過restApi 與es交互
幾個很經常使用的接口:
/_cat 查看可用命令
/_cat/nodes?v:查集羣狀態
/_cat/health?v:查詢集羣健康狀態
/_cat/shards?v:查看分片狀態
/${index}/${type}/_search?pretty:搜索
/${index}/_search?pretty&q=xxx=xxx:帶條件搜索
/_search?pretty :查詢所有文檔或/_count?pretty
(uri後面加?v 表示 對查詢結果按類型分列展現;?pretty 表示對結果格式化輸出)
查看es 可用索引http://10.6.129.101:9200/_cat/indices?v
索引僱員文檔
實踐中這很是簡單(儘管看起來有不少步驟),咱們能夠經過一條命令完成全部這些動做:
(拷貝下列代碼 到kibana DevTools模塊 中運行 是一個很方便的方法)
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
注意,路徑 /megacorp/employee/1 包含了三部分的信息:
megacorp
索引名稱
employee
類型名稱
1
特定僱員的ID
接着 再寫入兩條
PUT /megacorp/employee/2
{
"first_name" : "Jane",
"last_name" : "Smith",
"age" : 32,
"about" : "I like to collect rock albums",
"interests": [ "music" ]
}
PUT /megacorp/employee/3
{
"first_name" : "Douglas",
"last_name" : "Fir",
"age" : 35,
"about": "I like to build cabinets",
"interests": [ "forestry" ]
}
查詢es全部索引http://10.6.129.101:9200/_cat/indices?v 能夠看到 新建立的megacorp 索引
檢索文檔
目前咱們已經在 Elasticsearch 中存儲了一些數據, 接下來就能專一於實現應用的業務需求了。
1)第一個需求是能夠檢索到單個僱員的數據。
GET /megacorp/employee/1
將 HTTP 命令由 改成 能夠用來檢索文檔,一樣的,可使用 命令來刪除文檔,以及使用 指令來檢查文檔是否存在。若是想更新已存在的文檔,只需再次 PUTGETDELETEHEADPUT
2)咱們使用下列請求來搜索全部僱員
GET /megacorp/employee/_search
3)接下來,嘗試下搜索姓氏爲 ``Smith`` 的僱員。爲此,咱們將使用一個 高亮 搜索,很容易經過命令行完成。這個方法通常涉及到一個 查詢字符串 (_query-string_) 搜索
GET /megacorp/employee/_search?q=last_name:Smith
咱們仍然在請求路徑中使用 端點,並將查詢自己賦值給參數 。返回結果給出了全部的 Smith_searchq=
4)Query-string 搜索經過命令很是方便地進行臨時性的即席搜索 ,但它有自身的侷限性(參見 輕量 搜索)。Elasticsearch 提供一個豐富靈活的查詢語言叫作 查詢表達式 , 它支持構建更加複雜和健壯的查詢。
領域特定語言 (DSL), 指定了使用一個 JSON 請求。咱們能夠像這樣重寫以前的查詢全部 Smith 的搜索 :
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
這個請求使用 JSON 構造,並使用了一個 查詢match
5)更復雜的搜索
如今嘗試下更復雜的搜索。 一樣搜索姓氏爲 Smith 的僱員,但此次咱們只須要年齡大於 30 的。查詢須要稍做調整,使用過濾器 filter ,它支持高效地執行一個結構化查詢。
GET /megacorp/employee/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": {
"range" : {
"age" : { "gt" : 30 }
}
}
}
}
}
這部分與咱們以前使用的 match 查詢 同樣。 |
|
這部分是一個 range 過濾器 , 它能找到年齡大於 30 的文檔,其中 gt 表示_大於(_great than)。 |
目前無需太多擔憂語法問題,後續會更詳細地介紹。只需明確咱們添加了一個 過濾器 用於執行一個範圍查詢,並複用以前的 match 查詢。如今結果只返回了一個僱員,叫 Jane Smith,32 歲。
6)全文搜索
截止目前的搜索相對都很簡單:單個姓名,經過年齡過濾。如今嘗試下稍微高級點兒的全文搜索——一項傳統數據庫確實很難搞定的任務。
搜索下全部喜歡攀巖(rock climbing)的僱員:
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
顯然咱們依舊使用以前的 match
查詢在about
屬性上搜索 「rock climbing」 。獲得兩個匹配的文檔:
{
...
"hits": {
"total": 2,
"max_score": 0.16273327,
"hits": [
{
...
"_score": 0.16273327,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
},
{
...
"_score": 0.016878016,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [ "music" ]
}
}
]
}
}
|
相關性得分 |
Elasticsearch 默認按照相關性得分排序,即每一個文檔跟查詢的匹配程度。第一個最高得分的結果很明顯:John Smith 的 about
屬性清楚地寫着 「rock climbing」 。
但爲何 Jane Smith 也做爲結果返回了呢?緣由是她的 about
屬性裏提到了 「rock」 。由於只有 「rock」 而沒有 「climbing」 ,因此她的相關性得分低於 John 的。
這是一個很好的案例,闡明瞭 Elasticsearch 如何 在 全文屬性上搜索並返回相關性最強的結果。Elasticsearch中的 相關性 概念很是重要,也是徹底區別於傳統關係型數據庫的一個概念,數據庫中的一條記錄要麼匹配要麼不匹配。
7)短語搜索
找出一個屬性中的獨立單詞是沒有問題的,但有時候想要精確匹配一系列單詞或者短語 。 好比, 咱們想執行這樣一個查詢,僅匹配同時包含 「rock」 和 「climbing」 ,而且 兩者以短語 「rock climbing」 的形式緊挨着的僱員記錄。
爲此對 match
查詢稍做調整,使用一個叫作 match_phrase
的查詢:
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
8)高亮搜索
許多應用都傾向於在每一個搜索結果中 高亮 部分文本片斷,以便讓用戶知道爲什麼該文檔符合查詢條件。在 Elasticsearch 中檢索出高亮片斷也很容易。
再次執行前面的查詢,並增長一個新的 highlight
參數:
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
當執行該查詢時,返回結果與以前同樣,與此同時結果中還多了一個叫作 highlight
的部分。這個部分包含了 about
屬性匹配的文本片斷,並以 HTML 標籤 <em></em>
封裝:
9)分析聚合
終於到了最後一個業務需求:支持管理者對僱員目錄作分析。 Elasticsearch 有一個功能叫聚合(aggregations),容許咱們基於數據生成一些精細的分析結果。聚合與 SQL 中的 GROUP BY
相似但更強大。
舉個例子,挖掘出僱員中最受歡迎的興趣愛好:
先開啓
PUT megacorp/_mapping/employee/
{
"properties": {
"interests": {
"type": "text",
"fielddata": true
}
}
}
執行
GET /megacorp/employee/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}
暫時忽略掉語法,直接看看結果:
{
...
"hits": { ... },
"aggregations": {
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "forestry",
"doc_count": 1
},
{
"key": "sports",
"doc_count": 1
}
]
}
}
}
能夠看到,兩位員工對音樂感興趣,一位對林地感興趣,一位對運動感興趣。這些聚合並不是預先統計,而是從匹配當前查詢的文檔中即時生成。若是想知道叫 Smith 的僱員中最受歡迎的興趣愛好,能夠直接添加適當的查詢來組合查詢:
GET /megacorp/employee/_search
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}
all_interests
聚合已經變爲只包含匹配查詢的文檔:
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "sports",
"doc_count": 1
}
]
}
聚合還支持分級彙總 。好比,查詢特定興趣愛好員工的平均年齡:
GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}
獲得的聚合結果有點兒複雜,但理解起來仍是很簡單的:
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2,
"avg_age": {
"value": 28.5
}
},
{
"key": "forestry",
"doc_count": 1,
"avg_age": {
"value": 35
}
},
{
"key": "sports",
"doc_count": 1,
"avg_age": {
"value": 25
}
}
]
}
輸出基本是第一次聚合的增強版。依然有一個興趣及數量的列表,只不過每一個興趣都有了一個附加的 avg_age
屬性,表明有這個興趣愛好的全部員工的平均年齡。
即便如今不太理解這些語法也沒有關係,依然很容易瞭解到複雜聚合及分組經過 Elasticsearch 特性實現得很完美。可提取的數據類型毫無限制。
這是一個關於 Elasticsearch 基礎描述的教程,且僅僅是淺嘗輒止,更多諸如 suggestions、geolocation、percolation、fuzzy 與 partial matching 等特性均被省略,以便保持教程的簡潔。但它確實突顯了開始構建高級搜索功能多麼容易。不須要配置——只須要添加數據並開始搜索!
刪除索引
DELETE megacorp
其餘的一些操做命令(
按時間查詢日誌(國際時間)
Try a test query to Elasticsearch based on the fields created by the grok
filter plugin. Replace $DATE with the current date, in YYYY.MM.DD format:
curl -XGET 'localhost:9200/logstash-$DATE/_search?pretty&q=response=200'
例如 http://10.6.129.101:9200/logstash-2017.08.12/_search?pretty&q=host=10.33.42.212
其中 host=xxx可替換爲host:xxx
按城市名稱查詢
curl -XGET 'localhost:9200/logstash-$DATE/_search?pretty&q=geoip.city_name=Buffalo'
)
Logstash 是一款強大的數據處理工具,它能夠實現數據傳輸,格式處理,格式化輸出,還有強大的插件功能,經常使用於日誌處理(運行環境jvm 8)
官網地址:https://www.elastic.co/products/logstash
官方文檔:https://www.elastic.co/guide/en/logstash
Logstash管道有兩個必需的元素,、,以及一個可選的元素,。輸入插件消費源數據,過濾器插件會按照你指定的方式修改數據,輸出插件將數據寫入到目的地(查看logstash安裝了哪些插件./bin/logstash-plugin list)。配置模板inputoutputfilter
input {{
}}
filter { filter {
}}
output {{
}}
示例 參見虛擬機10.6.129.101配置示例。
工做流程
Logstash 工做的三個階段:
input 數據輸入端,能夠接收來自任何地方的源數據。
Filter 數據中轉層,主要進行格式處理,數據類型轉換、數據過濾、字段添加,修改等,經常使用的過濾器以下。
output 是logstash工做的最後一個階段,負責將數據輸出到指定位置,兼容大多數應用,經常使用的有:
編解碼器能夠做爲輸入的流過濾器。編解碼器使您能夠輕鬆地將郵件的傳輸與序列化過程分開。流行的編解碼器包括json
,msgpack
和plain
(文本)。
測試您的Logstash,運行最基本的Logstash管道。
1)例如:shell標準輸入數據
cd logstash-5.5.1
bin / logstash -e'input {stdin {}} output {stdout {}}'
2)或 端口輸入,stdout輸出
input {
beats {
port => "5043"
}
}
output {
stdout { codec => rubydebug }
}
bin/logstash -f first-pipeline.conf --config.test_and_exit
bin/logstash -f first-pipeline.conf --config.reload.automatic
該--config.reload.automatic
選項啓用自動配置從新加載,以便您每次修改配置文件時沒必要中止並從新啓動Logstash。
過濾器插件使您可以將非結構化日誌數據進行結構化 參見演示平臺logstash 配置
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}"}
}
}
刪除註冊文件,讓filebeat 從新讀取日誌
sudo rm data/registry
geoip 補充ip信息 需下載geoip數據庫,或機器能連網
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}"}
}
geoip {
source => "clientip"
}
}
logstash配置文件基礎語法:
https://www.elastic.co/guide/en/logstash/5.5/event-dependent-configuration.html
https://www.elastic.co/guide/en/logstash/5.5/plugins-filters-grok.html
解析任意文本和結構。
Grok目前是logstash中將最壞的非結構化日誌數據解析爲結構化和可查詢的最佳方式。
此工具很是適用於syslog日誌,apache和其餘Web服務器日誌,mysql日誌以及一般爲人類而不是計算機消費而編寫的任何日誌格式。
默認狀況下,Logstash約有120種模式。你能夠在這裏找到他們:https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns。你能夠本身加入。(見patterns_dir
設定)
若是您須要幫助構建模式以匹配您的日誌,您會發現 http://grokdebug.herokuapp.com和http://grokconstructor.appspot.com/應用程序很是有用!
日誌:
55.3.244.1 GET /index.xml 15824 0.043
pattern:
%{IPV4:client} %{WORD:method} %{URIPATH:uri} %{INT:datalength} %{BASE16FLOAT:timecost}
輸出:
寫成配置:
input {
file {
path => "/var/log/http.log"
}
}
filter {
grok {
match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" }
remove_field => [ "message" ]
}
}
filebeat 配置 fields type
filebeat.prospectors:
- input_type: log
paths:
- /var/log/*.log
fields:
type: syslog
output.logstash:
hosts: ["localhost:5043"]
logstash 配置 input tritter ,out put file,其中output:elasticsearch 能夠填寫集羣多個節點,自動負載均衡。端口能夠不填,默認9200
input {
twitter {
consumer_key => "enter_your_consumer_key_here"
consumer_secret => "enter_your_secret_here"
keywords => ["cloud"]
oauth_token => "enter_your_access_token_here"
oauth_token_secret => "enter_your_access_token_secret_here"
}
beats {
port => "5043"
}
file {
path => 「/var/log/ apache/ access.log」
type => 「apache」 }
}
output {
elasticsearch {
hosts => ["IP Address 1:port1", "IP Address 2:port2", "IP Address 3"]
}
file {
path => "/path/to/target/file"
}
}
elsaticsearch 查詢 上面配置的filed type :
curl -XGET 'localhost:9200/logstash-$DATE/_search?pretty&q=fields.type:syslog'
查詢推特信息
curl -XGET 'http://localhost:9200/logstash-$DATE/_search?pretty&q=client:iphone'
logstash 啓停 /etc/init.d/logstash start
# 經過這種方式啓動,logstash會自動加載 /etc/logstash/conf.d/ 下的配置文件
或後臺命令行運行:
nohup /usr/share/logstash/bin/logstash -f /usr/share/logstash/bin/logstash.conf &>/dev/null &
哈希是以格式指定的鍵值對的集合"field1" => "value1"
。請注意,多個鍵值條目由空格分隔,而不是逗號。
例:
match => { 「field1」 => 「value1」 「field2」 => 「value2」 ... }
output -elasticsearch
https://www.elastic.co/guide/en/logstash/5.5/plugins-outputs-elasticsearch.html
index
id
添加一個獨特ID
的插件配置。若是沒有指定ID,Logstash將生成一個。強烈建議您在配置中設置此ID。當您有兩個或多個相同類型的插件時,例如,若是您有2個Grok過濾器,則此功能特別有用。在這種狀況下添加命名ID將有助於在使用監視API時監視Logstash。
輸出{
stdout {
id =>「my_plugin_id」
}
}
參考文檔http://tchuairen.blog.51cto.com/3848118/1840596/
其中nginx 日誌改json 格式的方法: 在http 域內 定義名爲json的log_format 格式,而後指定日誌文件access.log使用該格式:
access_log logs/access.log json;
最後從新加載,或重啓nginx 以生效
以下:
http {
log_format json '{"@timestamp":"$time_iso8601",'
'"slbip":"$remote_addr",'
'"clientip":"$http_x_forwarded_for",'
'"serverip":"$server_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"domain":"$host",'
'"method":"$request_method",'
'"requesturi":"$request_uri",'
'"url":"$uri",'
'"appversion":"$HTTP_APP_VERSION",'
'"referer":"$http_referer",'
'"agent":"$http_user_agent",'
'"status":"$status"}';
access_log logs/access.log json;
- input_type: log
paths:
- /usr/local/openresty/nginx/logs/access.log
fields:
type: nginxacclog
fields_under_root: true
.2017-08-13 12:42:25.112 MsgProcessThread-4 org.springframework.web.servlet.mvc.method INFO - ping from [/10.33.25.215:41542]
%{TIMESTAMP_ISO8601:time} %{USERNAME :thread} %{USERNAME:classpath} %{LOGLEVEL:loglevel} - %{GREEDYDATA:data}
logstash if else 語法
if EXPRESSION {
...
} else if EXPRESSION {
...
} else {
...
}
Discover 對日誌進行檢索查看
Visuallize 圖表可視化 配置;對特定規則聚合的數據進行圖表分析
Dashboard 將Visualize設置的圖表展現成儀表盤,有分組功能
Timelion 默認顯示的.es(*) 爲 es 文檔個數
Dev Tools 一個RestAPI Console 與elasticsearch 進行交互
Management 建立管理索引的地方 以及 其餘 的高級設置