Fluentd 的核心功能之一是提供強大的日誌格式化和輸出能力。開發者可以根據需求選擇合適的格式化器,例如簡單的 out_file、結構化的 json、以及適用於不同分隔符號的 ltsv 和 csv,或為了提升傳輸效率而使用 msgpack。設定上,可以調整分隔符號、欄位、時間格式等引數,靈活控制輸出結果。此外,Fluentd 支援將處理後的日誌事件輸出到各種後端系統,例如 MongoDB 和 Slack。透過 MongoDB 輸出外掛,可以將日誌儲存至指定的資料函式庫和集合,方便後續查詢和分析。而整合 Slack 等協作平台,則能即時通知團隊成員重要的日誌事件,提升團隊應變能力。實務上,可以結合緩衝機制,有效管理日誌流量並提高系統效能。
使用 Fluentd 輸出日誌事件的格式化選項
在 Fluentd 中,日誌事件的輸出格式化是一個重要的功能。本章節將探討不同的格式化選項,包括 out_file、json、ltsv、csv 和 msgpack。
4.2.1 out_file 格式化器
out_file 是最簡單的格式化器之一,它使用分隔符號來區分 time、tag 和 record 三個欄位。預設情況下,分隔符號是 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>
這個設定輸出 secondValue 和 thirdValue 兩個欄位,使用逗號作為分隔符號。
4.2.5 msgpack 格式化器
msgpack 格式化器使用 MessagePack 框架壓縮日誌事件記錄,通常用於 HTTP 輸出外掛。
使用範例
<format>
@type msgpack
</format>
這個設定將日誌事件以 MessagePack 格式輸出。
#### 內容解密:
- out_file:提供了基本的日誌格式化功能,可以根據需求調整輸出格式。
- json:將日誌事件轉換為 JSON 格式,便於後續處理和分析。
- ltsv 和 csv:提供了靈活的格式化選項,適合不同的應用場景。
- 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_mongo 和 out_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>
內容解密:
@type mongo:指定使用 MongoDB 外掛程式。@id mongo-output:為該輸出組態提供一個唯一識別符號。host localhost和port 27017:定義了 MongoDB 服務的主機和連線埠。database Fluentd和collection Fluentd:指定了將日誌事件儲存到的資料函式庫和集合。<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.txtfluentd -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>
組態解說:
- connection_string:定義了連線到 MongoDB 的字串,包括主機、埠和資料函式庫名稱。
- collection:指定了要寫入的集合名稱。
- buffer:定義了緩衝區的相關組態,如提交超時、重新整理間隔等。
將日誌事件變為可操作
要使日誌事件變為可操作,需要能夠將事件傳送到外部系統,並區分需要採取行動的日誌事件和僅提供資訊的日誌事件。
利用 Fluentd 將日誌事件轉化為可行的操作
在後續章節中,我們將討論如何分離或過濾出需要採取行動的日誌事件。但在這裡,我們可以先了解如何在日誌事件抵達分析平台並執行分析流程之前,使其變得可執行。
透過服務呼叫使日誌事件可執行
使日誌事件可執行的一種方法是呼叫一個獨立的應用程式,該應用程式能夠在接收到 API 呼叫後執行必要的修復操作。這可能像呼叫 Ansible Tower REST API 一樣複雜,以啟動一個範本作業來執行一些內務處理(例如,將日誌移動到歸檔儲存或告知 Kubernetes 有關 Pod 的內部狀態)。我們需要控制操作的頻率;像 flow_counter 和 notifier 這樣的外掛可以提供幫助。
要呼叫通用的 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 設定中的每個人都看到每個操作訊息?
message 和 message_keys 屬性與 message 一起使用,%s 用於指示所識別的有效載荷元素的值被插入的位置。message 中的參照與 message_keys 中列出的 JSON 有效載荷元素的順序序列相關。
title 和 title_keys 的工作方式與 message 和 message_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>
內容解密:
源組態:使用
dummy輸入外掛生成測試日誌事件。@type dummy指定了輸入外掛的型別。tag dummy為生成的事件設定了一個標籤,用於後續的匹配。dummy {"message": "This is a test message"}定義了生成的測試訊息內容。
匹配組態:將帶有
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,從而實作可行的操作和團隊協作。