在現代軟體開發中,有效地監控系統日誌對於快速診斷問題至關重要。分散式系統的日誌分散在各個節點,難以查詢和分析。集中式日誌系統可以彙整所有日誌,方便查詢和分析。ELK 堆積疊提供了一個完整的解決方案,結合了 Elasticsearch 的搜尋和分析能力、Logstash 的日誌收集和處理能力,以及 Kibana 的視覺化能力,讓開發者可以輕鬆地建構和管理集中式日誌監控系統。本文將詳細介紹如何使用 Ansible 佈署和組態 ELK 堆積疊,並示範如何收集、處理和視覺化日誌資料,幫助開發者提升系統監控效率。

集中式日誌記錄與監控的重要性

在大多數情況下,日誌訊息被寫入檔案中。雖然檔案不是儲存日誌的唯一方式,但由於大多數團隊都在使用根據檔案的日誌,因此我們將假設這也是您的情況。

日誌記錄的挑戰

當系統運作正常時,我們很少關注日誌內容。然而,當出現問題時,日誌就成了我們查詢問題根源的重要依據。然而,在實際情況中,除錯過程往往更加複雜。應用程式和服務之間通常存在相互關聯,很難確定哪一個是問題的根源。

舉例來說,一個服務可能無法例項化。經過一段時間的除錯後,我們可能會發現問題出在資料函式庫上。該服務無法連線到資料函式庫,導致啟動失敗。這種情況下,我們需要切換到資料函式庫的日誌來查詢問題的根源。

分散式系統中的日誌記錄挑戰

在分散式服務運作於叢集的情況下,情況變得更加複雜。哪個服務例項出現故障?它執行在哪個伺服器上?哪些上游服務發起了請求?該節點的記憶體和硬碟使用情況如何?正如您可能已經猜到的,找到、收集和過濾所需的資訊往往非常困難。系統越大,難度就越大。

集中式日誌記錄的必要性

對於所有非最簡單和最小的系統,集中式日誌記錄是必不可少的。我們需要一種方法來解析資料並將其傳送到中央資料函式庫,以便進行近乎實時的查詢和分析。同時,我們需要一個視覺化的平台來呈現資料,以便更好地理解和分析。

ELK 堆積疊(ElasticSearch、LogStash 和 Kibana)

ELK 堆積疊是一種免費、檔案齊全、效率高且廣泛使用的解決方案。ElasticSearch 是一種優秀的即時搜尋和分析資料函式庫,具有分散式、可擴充套件、高用性和複雜的 API。LogStash 允許我們集中處理資料,可以輕鬆擴充套件到自定義資料格式,並提供了許多外掛以滿足幾乎任何需求。Kibana 是一種分析和視覺化平台,具有直觀的介面,位於 ElasticSearch 之上。

# 建立環境
1 vagrant up cd prod logging
2
3 vagrant ssh cd

內容解密:

  1. vagrant up cd prod logging:此命令用於啟動三個虛擬機器:cdprodloggingcd 主要用於資源調配,而 prod 則充當生產伺服器。logging 虛擬機器則模擬一個生產伺服器,用於執行所有日誌記錄和監控工具。
  2. vagrant ssh cd:此命令用於透過 SSH 連線到 cd 虛擬機器,以便進行進一步的操作。

日誌記錄策略

我們將從最常用的場景開始,逐步探索更複雜和更有效的日誌記錄策略。在選擇工具之前,我們需要了解集中式日誌記錄的需求。ELK 堆積疊可以滿足這些需求,並且可以輕鬆擴充套件以滿足特定的需求。

集中式日誌記錄與監控:ELK 堆積疊的佈署與組態

在現代化的系統維運中,集中式日誌記錄與監控是不可或缺的一環。ELK 堆積疊(ElasticSearch、LogStash 和 Kibana)為我們提供了一套強大的解決方案。本文將介紹如何使用 Ansible 佈署 ELK 堆積疊,並對其組態進行詳細解析。

佈署 ELK 堆積疊

首先,我們需要使用 Ansible 來佈署 ELK 堆積疊。執行以下命令來執行 elk.yml playbook:

ansible-playbook /vagrant/ansible/elk.yml \
-i /vagrant/ansible/hosts/prod \
--extra-vars "logstash_config=file.conf"

該 playbook 的定義如下:

- hosts: logging
  remote_user: vagrant
  serial: 1
  roles:
    - common
    - docker
    - elasticsearch
    - logstash
    - kibana

ElasticSearch 佈署

ElasticSearch 是 ELK 堆積疊的核心元件,負責儲存和索引日誌資料。我們使用官方的 ElasticSearch 映象來佈署容器:

- name: Container is running
  docker:
    name: elasticsearch
    image: elasticsearch
    state: running
    ports:
      - 9200:9200
    volumes:
      - /data/elasticsearch:/usr/share/elasticsearch/data
    tags: [elasticsearch]

內容解密:

  1. 容器執行: 使用 Docker 映象 elasticsearch 建立一個名為 elasticsearch 的容器,並確保其正在執行。
  2. 埠對映: 將容器的 9200 埠對映到主機的 9200 埠,以便外部存取 ElasticSearch 的 API。
  3. 資料持久化: 將主機上的 /data/elasticsearch 目錄掛載到容器的 /usr/share/elasticsearch/data 目錄,實作資料持久化。

LogStash 組態與佈署

LogStash 負責收集、處理和轉發日誌資料。以下是 LogStash 的佈署和組態:

- name: Container is running
  docker:
    name: logstash
    image: logstash
    state: running
    expose:
      - 5044
      - 25826
      - 25826/udp
      - 25827
      - 25827/udp
    ports:
      - 5044:5044
      - 5044:5044/udp
      - 25826:25826
      - 25826:25826/udp
      - 25827:25827
      - 25827:25827/udp
    volumes:
      - /data/logstash/conf:/conf
      - /data/logstash/logs:/logs
    links:
      - elasticsearch:db
    command: logstash -f /conf/{{ logstash_config }}
    tags: [logstash]

內容解密:

  1. 容器執行: 使用 Docker 映象 logstash 建立一個名為 logstash 的容器,並確保其正在執行。
  2. 埠暴露: 暴露多個埠以支援不同的日誌收集協定。
  3. 組態掛載: 將主機上的 /data/logstash/conf 目錄掛載到容器的 /conf 目錄,將 /data/logstash/logs 目錄掛載到容器的 /logs 目錄。
  4. 連結 ElasticSearch: 將 LogStash 映象連結到 ElasticSearch 容器,並將其別名設為 db
  5. 啟動命令: 使用指定的組態檔案啟動 LogStash。

LogStash 的組態檔案 file.conf 定義了輸入和輸出外掛:

input {
  file {
    path => "/logs/**/*"
  }
}

output {
  stdout {
    codec => rubydebug
  }
  elasticsearch {
    hosts => db
  }
}

內容解密:

  1. 輸入外掛: 使用 file 輸入外掛收集 /logs/ 目錄及其子目錄下的所有檔案。
  2. 輸出外掛: 將收集到的日誌輸出到標準輸出(使用 rubydebug 編碼)和 ElasticSearch(主機名為 db)。

Kibana 佈署

Kibana 提供了一個使用者介面,用於與 ElasticSearch 進行互動。以下是 Kibana 的佈署組態:

- name: Container is running
  docker:
    image: kibana
    name: kibana
    links:
      - elasticsearch:elasticsearch
    ports:
      - 5601:5601
    tags: [kibana]

內容解密:

  1. 容器執行: 使用 Docker 映象 kibana 建立一個名為 kibana 的容器,並確保其正在執行。
  2. 連結 ElasticSearch: 將 Kibana 映象連結到 ElasticSearch 容器。
  3. 埠對映: 將容器的 5601 埠對映到主機的 5601 埠,以便存取 Kibana 的 Web 介面。

透過以上步驟,我們成功佈署了 ELK 堆積疊並對其進行了基本組態。接下來,我們可以進一步探索 Kibana 的功能,以實作更強大的日誌分析和監控能力。

集中式日誌記錄與監控系統實務

在建置集中式日誌記錄與監控系統的過程中,LogStash 扮演著至關重要的角色。它能夠收集、處理並轉發日誌資料至 Elasticsearch,以供進一步的分析和視覺化。首先,我們需要驗證 LogStash 是否正確地監控了指定的日誌檔案。

驗證 LogStash 日誌處理流程

  1. 登入 logging 虛擬機器:

    vagrant ssh logging
    
  2. 由於 /data/logstash/logs 目錄與容器共用,我們可以在該目錄下建立一個新的日誌檔案,並觀察 LogStash 的反應:

    echo "我的第一筆日誌記錄" > /data/logstash/logs/my.log
    
  3. 檢視 LogStash 的輸出結果:

    docker logs logstash
    

    輸出結果可能需要幾秒鐘的時間才會出現。如果沒有立即出現,請重新執行上述命令。輸出結果應該類別似如下:

    {
      "message" => "我的第一筆日誌記錄",
      "@version" => "1",
      "@timestamp" => "2016-02-01T18:01:04.044Z",
      "host" => "logging",
      "path" => "/logs/my.log"
    }
    

    從輸出結果中可以看到,LogStash 不僅處理了我們的日誌記錄,還增加了一些額外的資訊,如時間戳、主機名稱和日誌檔案路徑。

進一步測試 LogStash 的日誌處理能力

為了進一步驗證 LogStash 的功能,我們可以新增更多的日誌記錄到同一個檔案中:

echo "我的第二筆日誌記錄" >> /data/logstash/logs/my.log
echo "我的第三筆日誌記錄" >> /data/logstash/logs/my.log
docker logs logstash

輸出結果應該包含所有新增的日誌記錄,如下所示:

{
  "message" => "我的第一筆日誌記錄",
  "@version" => "1",
  "@timestamp" => "2016-02-01T18:01:04.044Z",
  "host" => "logging",
  "path" => "/logs/my.log"
}
{
  "message" => "我的第二筆日誌記錄",
  "@version" => "1",
  "@timestamp" => "2016-02-01T18:02:06.141Z",
  "host" => "logging",
  "path" => "/logs/my.log"
}
{
  "message" => "我的第三筆日誌記錄",
  "@version" => "1",
  "@timestamp" => "2016-02-01T18:02:06.150Z",
  "host" => "logging",
  "path" => "/logs/my.log"
}

使用 Kibana 視覺化日誌資料

現在,我們可以透過 Kibana 來視覺化這些日誌資料。請在瀏覽器中開啟 http://10.100.198.202:5601/。首次執行 Kibana 時,需要組態索引模式。Kibana 已經自動偵測到了索引格式(logstash-*)以及包含時間戳的欄位(@timestamp)。請點選「Create」按鈕,然後點選頂部選單中的「Discover」。

圖表說明:Kibana Discover 螢幕擷取畫面

此圖示顯示了 Kibana Discover 螢幕,其中包含了多筆日誌記錄。

分析複雜的日誌資料

為了增加日誌資料的複雜度,我們可以使用預先準備好的 Apache 日誌範例。該範例包含了多筆遵循 Apache 格式的日誌記錄。

Apache 日誌範例內容

127.0.0.1 - - [11/Dec/2015:00:01:45 -0800] "GET /2016/01/11/the-devops-2-0-toolkit/ HTTP/1.1" 200 3891 "http://technologyconversations.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0"
127.0.0.1 - - [11/Dec/2015:00:01:57 -0800] "GET /2016/01/18/clustering-and-scaling-services/ HTTP/1.1" 200 3891 "http://technologyconversations.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0"
127.0.0.1 - - [11/Dec/2015:00:01:59 -0800] "GET /2016/01/26/self-healing-systems/ HTTP/1.1" 200 3891 "http://technologyconversations.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0"

將上述日誌內容追加到 /data/logstash/logs/apache.log 中:

cat /tmp/apache.log >> /data/logstash/logs/apache.log

LogStash 處理結果

{
  "message" => "127.0.0.1 - - [11/Dec/2015:00:01:45 -0800] \"GET /2016/01/11/the-devops-2-0-toolkit/ HTTP/1.1\" 200 3891 \"http://technologyconversations.com\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0\"",
  "@version" => "1",
  "@timestamp" => "2016-02-01T19:06:21.940Z",
  "host" => "logging",
  "path" => "/logs/apache.log"
}
{
  "message" => "127.0.0.1 - - [11/Dec/2015:00:01:57 -0800] \"GET /2016/01/18/clustering-and-scaling-services/ HTTP/1.1\" 200 3891 \"http://technologyconversations.com\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0\"",
  "@version" => "1",
  "@timestamp" => "2016-02-01T19:06:21.949Z",
  "host" => "logging",
  "path" => "/logs/apache.log"
}
{
  "message" => "127.0.0.1 - - [11/Dec/2015:00:01:59 -0800] \"GET /2016/01/26/self-healing-systems/ HTTP/1.1\" 200 3891 \"http://technologyconversations.com\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0\"",
  "@version" => "1",
  "@timestamp" => "2016-02-01T19:06:21.949Z",
  "host" => "logging",
  "path" => "/logs/apache.log"
}

這些資料也可以在 Kibana 中觀看,網址為 http://10.100.198.202:5601/。透過上述步驟,我們成功地使用 LogStash 和 Kibana 建置了一個基本的集中式日誌記錄與監控系統。