配置文件自己很是脆弱!因此修改配置文件天然會引入部署失敗的風險。若是可以對配置文件進行自動化測試將會極大的下降這種風險。本文將介紹一個能夠自動化測試 logstash 配置文件的工具,讓你們能夠像寫單元測試用例同樣爲 logstash 配置文件建立測試 case,並以快速迭代的方式變動 logstash 配置文件。git
在不少真實環境中,變動 logstash 的配置文件幾乎是個噩夢。日誌不是結構化的格式(甚至是亂七八糟!),致使咱們幾乎必須一個一個地處理日誌,並對解析什麼和不解析什麼作出邏輯斷定。這會致使咱們在 logstash 的配置文件中寫出複雜的日誌處理邏輯。更加悲催的是,咱們編寫的僅僅是一個配置文件,大多數時候你找不到像 VisualStudio 那樣豪華的帶有拼寫檢查和語法檢查的編輯工具。因此咱們迫切的須要一個能夠對 logstash 的配置文件作單元測試的工具,讓咱們更好的控制變動、執行迭代。github
logstash-test-runner 就是這樣一個可讓咱們應用 DevOps 原則來解決這個問題的工具。它具備下面幾個特色:docker
logstash-test-runner 的做者應該是飽受 logstash 的配置文件蹂躪以後建立的這個工具,因此這是一個寫給本身用的工具,在使用的時候你可以切身體會到它的便利!npm
運行 logstash-test-runner 依賴於下面三個條件:框架
其中 logstash 的測試用例是在 docker 容器中運行的,默認使用的鏡像中 logstash 的版本爲 5.5.1,咱們能夠經過第二個命令行參數指定其它的版本。工具
NodeJS 程序用來對比實際運行的輸出結果與指望的輸出結果。單元測試
logstash-test-runner 其實就是一個 Bash 腳本,把上面的工具組織起來完成任務。學習
在運行 logstash-test-runner 前請確保你的環境知足上述條件。而後從這裏克隆 logstash-test-runner。若是你肯定你要運行的 logstash 的版本,最好是提早先把對應的容器鏡像拉下來,好比筆者最經常使用的是 logstash 6.2.4:測試
$ docker pull docker.elastic.co/logstash/logstash:6.2.4
準備就緒,讓咱們先運行下 logstash-test-runner 內置的 demo 體驗一下。進入到 logstash-test-runner 目錄下,執行下面的命令:spa
$ npm install $ ./test.sh __tests__
test.sh 腳本的第一個參數是保存測試用例的根目錄,第二個參數是 logstash 的 docker 鏡像。也能夠不指定 logstash 鏡像,默認使用的鏡像中的 logstash 版本爲 5.5.1。該命令執行的結果以下:
__tests__ 目錄的結構以下:
每一個子目錄表明一個測試用例,demo 中有三個測試用例,分別是 clustering、crawlers 和 mongo。每一個測試用例下有三個文件,分別是 input.log、logstash.conf 和 output.log,他們的名稱是固定的。input.log 模擬日誌文件,保存的是日誌記錄;logstash.conf 則是待測的 logstash 配置文件;output.log 中是須要咱們寫入的指望結果(這就是 logstash 版的單元測試呀!)。
下面咱們添加本身的測試用例來測試 multiline 功能(把應用程序中的異常堆棧合併到一條日誌記錄中)。先建立目錄 __nick__/mlines,而後在 __nick__/mlines 目錄中建立文件 input.log、logstash.conf 和 output.log。input.log 文件的內容以下:
2019-1
hello
world
2019-2
aa
2019-3
bb
2019-4
模擬的日誌記錄以日期開頭,非數字開頭的記錄則是異常堆棧。
logstash.conf 文件的內容以下:
input { stdin { codec => multiline { pattern => "^\d" negate => "true" what => "previous" } } } filter { mutate { replace => { "host" => "testing_host" } } }
filter 中設置 host 主要目的是讓測試用例忽略真正的 host 值(在容器中運行這個值是隨機的字符串,沒法執行比較操做,因此老是讓他輸出 testing_host)。
output.log 文件的內容以下:
{"tags":["multiline"],"host":"testing_host","message":"2019-1\nhello\nworld","@version":"1","@timestamp":"2019-03-05T09:30:26.820Z"} {"tags":["multiline"],"host":"testing_host","message":"2019-2\naa","@version":"1","@timestamp":"2019-03-05T09:30:26.823Z"} {"tags":["multiline"],"host":"testing_host","message":"2019-3\n bb","@version":"1","@timestamp":"2019-03-05T09:30:26.824Z"}
這是咱們指望 logstash 輸出的 JSON 格式的日誌記錄。固然,在默認狀況下 logstash-test-runner 會忽略 @timestamp。
接下來執行下面的命令運行測試:
$ ./test.sh __nick__ docker.elastic.co/logstash/logstash:6.2.4
該命令中筆者指定了 logstash 鏡像,因此測試用例都是由 logstash 6.2.4 執行的,結果以下:
上圖顯示測試用例都經過了。若是有測試用例失敗,就會輸出詳細的失敗信息,很是有助於排除問題。
logstash-test-runner 很是簡單易用,其實在整個使用過程當中,筆者以爲寫 output.log 是最困難的。由於你很難根據日誌記錄和 logstash 的配置文件直接推導出 logstash 輸出的記錄應該是什麼樣子的。logstash-test-runner 直接把 logstash 輸出的日誌記錄輸出到了 console 中:
這樣咱們就能夠輕鬆的根據 console 中的輸出來調整 output.log 文件了!
使用者爲本身編寫的工具每每是直擊痛點,logstash-test-runner 就是這樣的工具。它讓咱們能夠快速迭代 logstash 的配置變動。咱們還能夠自動化的執行 logstash-test-runner,做爲 CI/CD 的一部分,從而確保每一個配置變動都經過了測試。
對 logstash 之類的基礎設施工具進行測試符合 DevOps(構建→測試→發佈→運行)的實踐。我想測試基礎設施配置的實踐會愈來愈廣泛,而且在提升基礎設施可靠性和交付方面體現出巨大的價值。