ELK Stack with Docker

因為工作需要,自己研究了一下Docker ELK stack, 以下是之前的一些筆記
截圖的部分都是自己測試時用的Machine
Docker會因為OS有些不同的Bug,本篇是在OS Win7 64bit下運行~
基於一些考量,我們是採取一段時間拿Log
而非同步Stream Log出來的方式,所以這邊就沒特別討論Stream log的部分

背景說明:
在Log管理與分析領域裡,目前主流架構為三個開源專案所組成:Elasticsearch、Logstash、Kibana (簡稱ELK) 
Logstash負責蒐集、過濾、標記每份Log,並將處理過的Log輸出
Elasticsearch則扮演資料倉儲的角色,可以透過Rest api進行資料的CRUD,但並不等於資料庫
Kibana則是提供Web GUI介面,以視覺化的方式呈現Log的統計分析資料  

以下,將從部屬到三部分的基本操作開始說明


0. 環境部署

(1) 完成Docker的基本安裝,確認可以正常Run Image
(2) git clone docker-elk project
(3) 在 ~/docker-elk 下,執行docker-compose up
Note: 如果Elasticsearch開啟時會有 vm.max_map_count [65530] too low的問題 
透過 docker-machine ssh default 指令進入docker-machine後,輸入以下指令* :


解決 vm.max_map_count問題
1
sudo sysctl -w vm.max_map_count=262144

*每次docker machine重啟都要重新設定, 尚在尋找更好的做法

1. Logstash 參數設定

針對特定log,我們可能希望能夠標記,filter rule裡的grok plug-in可以幫忙做到正規表示式與標記的功能
這裡主要講解如何設定客製化的 filter rule,grok裡頭已有許多內建的Pattern,請參考這裡

~/docker-elk/logstash/pipeline/patterns/YOUR_PATTERN
1
 EXCEPTION ([a-zA-Z.]+(?:Error|Exception): +) 

格式(注意有一格空格):[Pattern名稱] [正規表示式]
可透過 grokdebugger 驗證表示式是否正確,範例如下:


~/docker-elk/logstash/pipeline/logstash.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
input {
    ## 接收tcp connection的port,可以多個tcp設定
    tcp {
        port => 5000
    }
    ## 監聽某資料夾底下的檔案,就算是同檔名,一發現有修改亦會觸發,此範例放在 ~/docker-elk/logstash/logs 底下
    file {
        path => "/usr/share/logstash/logs/*.log"
    }
}
## Add your filters / logstash plugins configuration here
filter {
    grok {
        ## 參考客製化Pattern路徑
        patterns_dir => ["/usr/share/logstash/pipeline/patterns"]
        match => {
            ##在Message欄位中,有符合EXCEPTION這個Pattern,即設定一組KeyValue為 ExceptionType:EXCEPTION的Field
            "message" => "%{EXCEPTION:ExceptionType}"
        }
    }
}
output {
    elasticsearch {
        hosts => "elasticsearch:9200"
        ## 亦可設定自製的index => "CUSTOM_INDEX",若無設定logstash會自動幫你產生 logstash-yyyy.mm.dd的index
    }
}
*設定好之後重啟服務,如果設定正確即可正常啟動

2. 透過Elasticsearch api拿取資料

資料結構基本說明:
Elasticsearch的資料結構主要由Index、Type、Id為一筆Unique的資料基本概念 GET http://192.168.99.100:9200/_index/_type/_id 即可找到指定的log

Elastic search 回傳資料範例
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
    "_index": "logstash-2017.04.10",
    "_type": "logs",
    "_id": "AVtV2QKKRNF__nCpAPa8",
    "_score": 1,
    "_source": {
        "ExceptionType": "com.microsoft.sqlserver.jdbc.SQLServerException: ",
        "@timestamp": "2017-04-10T03:12:17.021Z",
        "port": 64826,
        "@version": "1",
        "host": "192.168.99.1",
        "message": "Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection ...省略... "
    }
}

REST API範例 (以自定義欄位為例), 用PostMan自己打更好 :
Elasticsearch GET 範例
1
2
3
4
5
6
7
8
# 顯示該index底下所有log
GET http://192.168.99.100:9200/logstash-2017.04.10/_search
# 搜尋特定欄位的值
GET http://192.168.99.100:9200/logstash-2017.04.10/_search?q=ExceptionType:com.microsoft.sqlserver.jdbc.SQLServerException
# 只拿取回傳結果的特定欄位
GET http://192.168.99.100:9200/logstash-2017.04.10/_search?_source_include=ExceptionType
# 只拿取特定資料回傳結果的特定欄位
GET http://192.168.99.100:9200/logstash-2017.04.10/logs/AVtH-OPRRNF__nCpAPae?_source_include=ExceptionType

3. Kibana 搜尋

(1). Index Pattern Configuration

開啟Kibana 或有新的自定義Tag後,務必要到 Management建立或更新Index Pattern
建立Index Pattern (使用預設設定,點選Create即可)
更新Index Pattern

(2). 搜尋

Kibana是以單字為index建立搜尋,搜尋時可利用*等正規表示式搜尋來慢慢精確找到自己要的資訊
以前述自定義標記 "ExceptionType": "com.microsoft.sqlserver.jdbc.SQLServerException: " 為例,有幾種搜尋方式
Note: com.microsoft.sqlserver.jdbc.SQLServerException 算一個單字
A. com.microsoft.sqlserver.jdbc.SQLServerException
B. *SQLServerException
C. ExceptionType:*SQLServerException (Tag:Value)
以C為例:
 
Note1: ElasticSearch + Kibana 可以使用 X-Pack 模組,有認證授權以及Monitoring的功能,但要與他們的業務談授權費,目前是關閉此功能的

Note2: 若要由各Node主動Stream Log到 Elastic Search, 除了Logstash, 亦可參考 Beats

以上,如果有任何疑問或是覺得撰寫錯誤的地方,還請大家多多指教 <(_ _)>
BTW, 打這篇 Code Snippet 用了三種,覺得http://hilite.me/ 簡單又好用

留言