返回文章列表

Fluentd 日誌格式化與輸出整合

Fluentd 提供多樣化日誌格式選項,包含 out_file、json、ltsv、csv 和 msgpack,滿足不同情境需求。文章探討各格式的設定屬性和使用方法,並解析如何將日誌輸出至 MongoDB 和 Slack 等外部系統,以及如何運用緩衝機制提升效能。此外,文章也提供 MongoDB

Web 開發 系統設計

Fluentd 的核心功能之一是提供強大的日誌格式化和輸出能力。開發者可以根據需求選擇合適的格式化器,例如簡單的 out_file、結構化的 json、以及適用於不同分隔符號的 ltsvcsv,或為了提升傳輸效率而使用 msgpack。設定上,可以調整分隔符號、欄位、時間格式等引數,靈活控制輸出結果。此外,Fluentd 支援將處理後的日誌事件輸出到各種後端系統,例如 MongoDB 和 Slack。透過 MongoDB 輸出外掛,可以將日誌儲存至指定的資料函式庫和集合,方便後續查詢和分析。而整合 Slack 等協作平台,則能即時通知團隊成員重要的日誌事件,提升團隊應變能力。實務上,可以結合緩衝機制,有效管理日誌流量並提高系統效能。

使用 Fluentd 輸出日誌事件的格式化選項

在 Fluentd 中,日誌事件的輸出格式化是一個重要的功能。本章節將探討不同的格式化選項,包括 out_filejsonltsvcsvmsgpack

4.2.1 out_file 格式化器

out_file 是最簡單的格式化器之一,它使用分隔符號來區分 timetagrecord 三個欄位。預設情況下,分隔符號是 tab 字元,但可以透過設定 delimiter 屬性來更改為逗號或空格。

設定屬性

  • output_tag:決定是否在輸出中包含 tag,預設為 true。
  • output_time:決定是否在輸出中包含時間,預設為 true。
  • time_format:定義時間的格式。

使用範例

<format>
  @type out_file
  delimiter comma
  output_tag false
</format>

這個設定使用逗號作為分隔符號,並且不輸出 tag 資訊。

4.2.2 json 格式化器

json 格式化器將日誌事件記錄視為 JSON 負載,並捨棄 timestamp 和 tags。

使用範例

<format>
  @type json
</format>

這個設定將日誌事件以 JSON 格式輸出。

4.2.3 ltsv 格式化器

ltsv 格式化器允許更改分隔符號和標籤分隔符號,並且可以關閉換行符號以分隔記錄。

設定屬性

  • delimiter:定義每個標籤值的分隔符號。
  • label_delimiter:定義標籤和值的分隔符號。
  • add_newline:決定是否在每個記錄後新增換行符號,預設為 true。

使用範例

<format>
  @type ltsv
  delimiter ;
  label_delimiter =
</format>

這個設定使用分號作為標籤值的分隔符號,並且使用等號作為標籤和值的分隔符號。

4.2.4 csv 格式化器

csv 格式化器允許定義分隔符號和輸出的欄位。

設定屬性

  • delimiter:定義欄位之間的分隔符號,預設為逗號。
  • fields:定義要輸出的欄位。
  • force_quotes:決定是否強制為每個值新增引號。

使用範例

<format>
  @type csv
  delimiter ,
  fields secondValue,thirdValue
</format>

這個設定輸出 secondValuethirdValue 兩個欄位,使用逗號作為分隔符號。

4.2.5 msgpack 格式化器

msgpack 格式化器使用 MessagePack 框架壓縮日誌事件記錄,通常用於 HTTP 輸出外掛。

使用範例

<format>
  @type msgpack
</format>

這個設定將日誌事件以 MessagePack 格式輸出。

#### 內容解密:

  1. out_file:提供了基本的日誌格式化功能,可以根據需求調整輸出格式。
  2. json:將日誌事件轉換為 JSON 格式,便於後續處理和分析。
  3. ltsvcsv:提供了靈活的格式化選項,適合不同的應用場景。
  4. msgpack:透過壓縮日誌事件提高了傳輸效率,適合高效能需求的場景。

將日誌事件傳送至 MongoDB

佈署 MongoDB Fluentd 外掛程式

Treasure Data Agent 版本的 Fluentd 提供了 MongoDB 輸入外掛程式,但在原生佈署中並未包含此功能。如果我們希望 Fluentd 能夠與 MongoDB 協同工作,就需要安裝 RubyGem。

為了確定是否需要安裝以及執行 Gem 的安裝,我們可以使用一個名為 fluent-gem 的包裝工具,它利用了 RubyGems 工具。要檢查 Gem 是否已經安裝,可以在命令列中執行 fluent-gem list 命令。此命令將顯示本地安裝的 Gem,其中包括 Fluentd 及其外掛程式。目前不應有 fluent-plugin-mongo Gem 的任何跡象。因此,我們可以使用 fluent-gem install fluent-plugin-mongo 命令進行安裝。這將檢索並安裝最新穩定的 Gem 例項,包括檔案和依賴項,例如 MongoDB 驅動程式。

MongoDB 簡介

我們不希望過於探討 MongoDB 的機制,但有必要總結一些基本概念。大多數讀者都熟悉關聯式資料函式庫及其概念。MongoDB 和關聯式資料函式庫中的資料函式庫結構角色是類別似的。在資料函式庫架構中,有一組表格。在 MongoDB 中,與此最接近的是集合(collection)。與關聯式資料函式庫不同,集合可以包含幾乎任何內容,這就是為什麼它有時被描述為使用檔案模式。你可以說集合中的每個條目大致相當於表格中的一筆記錄,包含一個由資料函式庫分配的 ID 和一個 BLOB(二進位大型物件)或文字資料型別。通常,MongoDB 的列或檔案是一個結構化的文字物件,通常是 JSON。MongoDB 可以搜尋和索引這些結構的部分,從而提供了一個靈活的解決方案。對於 Fluentd 來說,這意味著我們可以儲存可能具有不同記錄結構的日誌事件。

設定 MongoDB 輸出外掛程式

在匹配(match)中,我們需要參照 Mongo 外掛程式並設定相關屬性。就像連線到任何資料函式庫一樣,我們需要提供位址(可以透過主機名稱和連線埠號實作)和使用者名稱與密碼,或者透過連線字串(例如 mongodb://127.0.0.1:27017/Fluentd)。在我們的範例組態中,我們採用了前一種方法,並避免了憑證問題。需要指定資料函式庫(架構)和集合(類別似於關聯式表格),以便知道將日誌事件放在哪裡。

在 MongoDB 輸出中,不使用格式化工具,因為 MongoDB 外掛程式假設所有內容都已經結構化。正如我們所見,沒有組態的話,將採用預設的緩衝區。與之前一樣,我們將保持緩衝區設定,以支援較低的日誌量,以便快速看到變化。

<match *>
  @type mongo
  @id mongo-output
  host localhost
  port 27017
  database Fluentd
  collection Fluentd
  <buffer>
    delayed_commit_timeout 10
    flush_at_shutdown true
    chunk_limit_records 50
    flush_interval 30
    flush_mode interval
  </buffer>
</match>

Mongo 與 Mongo 複製集外掛程式的比較

如果你檢視過 Fluentd 的線上檔案,你可能會發現兩個輸出外掛程式:out_mongoout_mongo_replset。兩者的主要區別在於 replset(複製集)可以支援 MongoDB 的擴充套件方式,即定義額外的 Mongo 例項作為主例項的副本。在這種情況下,理想的模型是直接將活動寫入主例項,但從副本讀取。在組態差異方面,需要提供一個以逗號分隔的節點列表,而不是命名單一主機。每個節點代表複製群組中的一個節點。

程式碼詳細解析

<match *>
  @type mongo
  @id mongo-output
  host localhost
  port 27017
  database Fluentd
  collection Fluentd
  <buffer>
    delayed_commit_timeout 10
    flush_at_shutdown true
    chunk_limit_records 50
    flush_interval 30
    flush_mode interval
  </buffer>
</match>

內容解密:

  1. @type mongo:指定使用 MongoDB 外掛程式。
  2. @id mongo-output:為該輸出組態提供一個唯一識別符號。
  3. host localhostport 27017:定義了 MongoDB 服務的主機和連線埠。
  4. database Fluentdcollection Fluentd:指定了將日誌事件儲存到的資料函式庫和集合。
  5. <buffer> 部分:定義了緩衝區的行為,包括提交超時、關閉時重新整理、記錄限制、重新整理間隔和重新整理模式。

這些設定確保日誌事件能夠有效地被傳送到指定的 MongoDB 資料函式庫和集合中,並且透過緩衝區組態最佳化了日誌處理的效率。

將日誌事件傳送至 MongoDB

要將日誌事件傳送至 MongoDB,首先需要確保 MongoDB 例項正在執行。可以在 shell 視窗中使用 mongod --version 命令或嘗試使用 Compass UI 連線到伺服器來檢查。如果 MongoDB 伺服器未執行,則需要啟動它。最簡單的方法是執行 mongod 命令。

執行日誌模擬器與 Fluentd 組態

在 MongoDB 執行後,可以透過以下命令執行模擬日誌和 Fluentd 組態:

  • groovy LogSimulator.groovy Chapter4/SimulatorConfig/jul-log-file2-exercise.properties ./TestData/medium-source.txt
  • fluentd -c Chapter4/fluentd/rotating-file-read-mongo-out.conf

檢視 MongoDB 中的日誌事件

使用 Compass 導航到 Fluentd 資料函式庫,並點選 Fluentd 集合,以檢視集合中的內容,如圖 4.2 所示。

在 MongoDB 中查詢日誌事件

要在 MongoDB 中查詢 JSON 日誌事件,可以在 FILTER 欄位中輸入表示式 {"msg" : {$regex : ".*software.*"}},然後點選 FIND。這將顯示 msg 欄位包含 “software” 的日誌事件。

MongoDB 組態與警告處理

當 Fluentd 使用 MongoDB 外掛程式啟動時,會記錄一條警告,指出 MongoDB 驅動程式不對負載進行結構檢查,可能導致資料丟失。

清空集合

要清空集合,可以在命令列中執行 mongo Fluentd –-eval "db.Fluentd.remove({})" 命令。

動態集合建立與組態

MongoDB 外掛程式支援動態建立集合,並可透過 tag_mapped 屬性將標籤名稱用作集合名稱。同時,可以使用 remove_tag_prefix 屬性簡化標籤名稱。

連線組態字串的使用

可以透過 connection_string 屬性定義 MongoDB 連線,而不是使用主機、埠和資料函式庫屬性。例如:

<match *>
  @type mongo
  @id mongo-output
  connection_string mongodb://localhost:27017/Fluentd
  collection Fluentd
  <buffer>
    delayed_commit_timeout 10
    flush_at_shutdown true
    chunk_limit_records 50
    flush_interval 30
    flush_mode interval
  </buffer>
</match>

組態解說:

  1. connection_string:定義了連線到 MongoDB 的字串,包括主機、埠和資料函式庫名稱。
  2. collection:指定了要寫入的集合名稱。
  3. buffer:定義了緩衝區的相關組態,如提交超時、重新整理間隔等。

將日誌事件變為可操作

要使日誌事件變為可操作,需要能夠將事件傳送到外部系統,並區分需要採取行動的日誌事件和僅提供資訊的日誌事件。

利用 Fluentd 將日誌事件轉化為可行的操作

在後續章節中,我們將討論如何分離或過濾出需要採取行動的日誌事件。但在這裡,我們可以先了解如何在日誌事件抵達分析平台並執行分析流程之前,使其變得可執行。

透過服務呼叫使日誌事件可執行

使日誌事件可執行的一種方法是呼叫一個獨立的應用程式,該應用程式能夠在接收到 API 呼叫後執行必要的修復操作。這可能像呼叫 Ansible Tower REST API 一樣複雜,以啟動一個範本作業來執行一些內務處理(例如,將日誌移動到歸檔儲存或告知 Kubernetes 有關 Pod 的內部狀態)。我們需要控制操作的頻率;像 flow_counternotifier 這樣的外掛可以提供幫助。

要呼叫通用的 Web 服務,我們可以使用 Fluentd 核心中的 HTTP 輸出外掛。以下是該外掛支援的一般功能的總結:

  • 支援 HTTP POST 和 PUT 操作
  • 允許在路由中使用代理
  • 組態內容型別,並自動設定格式化器(也可以明確定義格式化器)
  • 定義標頭,以便定義額外的標頭值(例如,API 金鑰)
  • 組態連線以使用 SSL 和 TLS 證書,包括定義要使用的證書位置、版本、要使用的加密方式等
  • 當收到不成功的 HTTP 程式碼回應時建立日誌錯誤
  • 支援基本身份驗證(在寫作時不支援 OAuth)
  • 設定超時
  • 使用緩衝區外掛

透過使用者互動工具使日誌事件可執行

雖然以這種方式自動解決問題使我們朝著自我修復系統的方向邁進,但並非所有組織都準備好或願意達到這種高度自動化的程度。他們更願意相信快速的人工干預來確定因果關係,而不是依賴一個自動診斷,因為高精確度可能難以保證。具備足夠知識和適當資訊的人員可以快速確定和解決這些問題。因此,Fluentd 有一套豐富的外掛,用於社會協作機制。以下是一些例子:

  • IRC(網際網路中繼聊天)
  • Twilio(支援許多不同的通訊通路)
  • Jabber
  • Redmine
  • Typetalk
  • PagerDuty
  • Yammer
  • Slack

顯然,我們需要在社會通路通訊中包含相關資訊。可以透過多種方式來實作這一點,從良好的日誌事件到將相關資訊從日誌事件中提取出來進行分享。

以 Slack 為例演示社會輸出

Slack 已成為領先的團隊訊息協作工具,具有強大的 API 層和免費版本,僅受限於對話存檔的大小。作為一個雲端服務,它是一個很好的工具,用於闡釋 Fluentd 和透過社會平台實作可行的日誌事件之間的交集。雖然以下步驟是針對 Slack 的,但所涉及的原理與 Microsoft Teams、Jabber 和許多其他協作服務相同。

如果你已經在使用 Slack,很容易想使用現有的群組來執行示例。為了避免因測試日誌事件而向頻道填充訊息,從而煩擾你的 Slack 工作區的其他使用者,我們建議設定自己的測試工作區。如果你不使用 Slack,也沒問題;在附錄 A 中,我們將解釋如何取得 Slack 帳戶並將其組態為可使用。確保在 Slack 組態過程中記下 API 令牌,該令牌具有 xoxb 字首。

Slack 提供了一套豐富的組態選項,用於互動。與 MongoDB 和許多 IaaS 和 PaaS 級別的外掛不同,由於 Slack 是一個 SaaS 服務,因此透過使用單個令牌(無需伺服器地址等),Slack 例項的解析既簡化又被隱藏。使用者名稱與憑據無關,而是與 Fluentd 外掛所表現的機器人的表示方式有關;因此,使用一個有意義的名稱是值得的。頻道與 Slack 頻道相關,傳送的訊息將在該頻道中顯示。general 頻道預設存在,但你可能希望在 Slack 中建立一個自定義頻道,並限制對該頻道的存取,如果你想控制誰可以看到訊息。畢竟,你是否希望企業 Slack 設定中的每個人都看到每個操作訊息?

messagemessage_keys 屬性與 message 一起使用,%s 用於指示所識別的有效載荷元素的值被插入的位置。message 中的參照與 message_keys 中列出的 JSON 有效載荷元素的順序序列相關。

titletitle_keys 的工作方式與 messagemessage_keys 類別似,但用於在 Slack UI 中顯示的訊息標題。在我們的例子中,我們將只使用標籤。最後一部分是 flush 屬性;這告訴外掛多快將 Slack 訊息推播給使用者。如果週期太長,則可以將多個訊息分組在一起。為了讓事情快速進行,讓我們每秒重新整理一次。

組態程式碼示例:

<source>
  @type dummy
  tag dummy
  dummy {"message": "This is a test message"}
</source>

<match dummy.**>
  @type slack
  webhook_url https://hooks.slack.com/services/YOUR/SLACK/WEBHOOKURL
  channel general
  username FluentdBot
  message This is a %s message
  message_keys message
  flush_interval 1s
</match>

內容解密:

  1. 源組態:使用 dummy 輸入外掛生成測試日誌事件。

    • @type dummy 指定了輸入外掛的型別。
    • tag dummy 為生成的事件設定了一個標籤,用於後續的匹配。
    • dummy {"message": "This is a test message"} 定義了生成的測試訊息內容。
  2. 匹配組態:將帶有 dummy 標籤的日誌事件匹配到 Slack 輸出外掛。

    • @type slack 指定了輸出外掛的型別為 Slack。
    • webhook_url 需要替換為你的 Slack webhook URL,用於將訊息傳送到 Slack。
    • channel general 指定了訊息要傳送到的 Slack 頻道。
    • username FluentdBot 定義了在 Slack 中顯示的機器人使用者名稱。
    • message This is a %s message 定義了要傳送的訊息格式, %s 將被 message_keys 中指定的值替換。
    • message_keys message 指定了用於替換 message 中的 %s 的鍵。
    • flush_interval 1s 設定了每秒重新整理一次訊息到 Slack。

此組態展示瞭如何利用 Fluentd 將日誌事件傳送到 Slack,從而實作可行的操作和團隊協作。