一套日誌收集系統實現
一套日誌管理系統實現
written by Alex Stocks on 2018/11/25,版權所有,無授權不得轉載
0 前述
前一篇博文 ofollow,noindex" target="_blank">一套實時監控告警系統實現 中提到 一個擺脫了手工作坊時代的可稱之為近代化的網際網路公司,如果想對自己的後臺服務以及各個使用者的客戶端的執行情況瞭如指掌,大概也需要自己的 “聽診器”:分散式實時監控告警系統、分散式日誌收集系統和分散式鏈路追蹤系統
。
實時監控告警系統基於固定的資料抽象模式能夠很快對服務端線上服務質量進行監控,而鏈路追蹤系統則主要用於分析服務質量和各個服務之間的呼叫關係,日誌收集系統主要用於大資料處理分析場景,為安全審計、客戶端產品開發以及服務端治理質量提高以及鏈路追蹤提供必要的支援。目前也有很多中小公司直接基於日誌收集系統進行服務的監控和告警,但是由於日誌收集系統一般處理的日質量比較大,幾乎不可能做到實時,個人強烈反對把日誌系統直接用於服務監控。
本文將詳細記述愚人 2018 年 Q2 實現的一套日誌收集系統以及其附屬的儲存和檢索系統的詳細工作流程,可認作是前一篇博文 一套實時監控告警系統實現 的續貂之作。
1 日誌系統
網際網路公司的日誌資料可以區分為客戶端日誌和服務端日誌,兩種日誌來源、內容形態、收集方式、處理方法均不一樣,下面先給出愚人實現的系統的總體架構,然後再分章節詳細介紹各個子模組的工作流程。
1.1 總體架構
日誌管理系統分為日誌收集、資料清洗、日誌儲存、資料檢索和資料分析等眾多子模組,囿於本人大資料系統經驗不足,此日誌系統不涉及與之相關的部分。
本系統考慮到公司服務端業務跨 IDC 特點,其總體架構如下:
1.2 各模組解釋
總架構圖中給出了日誌收集的詳細資料流向以及控制流程,本章對各個模組的功用進行詳細地解釋。
-
1 Log Agent
Log Agent 是服務端日誌收集的源頭,在每個服務節點(物理機或者虛機)都有部署,通過監聽 UDS(Unix Domain Socket)被動收集各個服務的日誌資料,而後根據 Service Name 傳送給每個服務對應的 Log Kafka 群集。
-
2 Log Kafka
Log Kafka 是系統最關鍵的節點,從 Log Agent 和客戶端 APP 接收日誌資料,而後根據 Service Name(客戶端相應欄位稱之為 BizType)寫入不同的 Kafka 通道(Topic)。
-
3 Registry
Registry 是系統的註冊中心,用於 Log Kafka 服務註冊和服務發現,並傳遞服務端日誌收集引數。
-
4 Kafka Connector
Kafka Connector 是系統的資料遷移節點,從 Kafka 不同通道讀取日誌資料 (Log Data)然後存入不同的 Elasticsearch Index。當然也會根據線上需要把資料存入 HDFS 以供大資料系統分析使用。
-
5 Console
Console 是系統的控制中心,用於設定客戶端的日誌收集方式以及服務端日誌的傳輸通道。
-
6 Es Log Server
Es Log Server 是系統的資料過濾和匯聚模組,用於日誌查詢。
-
7 Log View
Log View 是日誌資料的展示模組,根據使用者設定的引數向 Es Log Server 發出日誌查詢請求,並展示查詢結果。
2 服務端日誌收集處理
不同的服務有不同的服務名稱(Service Name),日誌系統進行日誌收集時,不同的服務使用不同的傳輸通道。
本文的日誌系統強制要求日誌資料採用 JSON 文字格式。下面先介紹服務端日誌資料的 schema,然後再介紹各個模組的處理流程。
2.1 服務端日誌格式
不同服務的日誌資料格式不可能相同,但為了便於日誌收集,需要約定一些共同的日誌欄位(Log Data Common Field)以便於日誌資料清洗和傳輸。
本系統規定的日誌格式如下:
{ “IP”: “10.10.10.10“, “Timestamp”: “20181125 16:38:32.112+08:00”, “ServerID”: 12345, “BizType”: “pubsub_proxy”, “BizAction”: “MsgAck”, “UserID”: 456789, “Log”: “xxx” }
各個欄位詳細意義如下:
- 1 IP: Host IP;
- 2 Timestamp: Log Data timestamp;
-
3 ServerID: 服務節點標識;
服務節點的 IP 會漂移,無法作為唯一標識,因此以 ServerID 代之,公司的 itil 系統會為每個服務節點分配一個唯一的 ServerID。
-
4 BizType: Service Name,服務名稱,類似於 Class Name;
-
5 BizAction: Service Action,類似於 Class Method;
-
6 UserID: 使用者 ID;
-
7 Log: Log Data,統一放入這個欄位中,用於大資料系統詳細分析處理。
公司主要 APP 是一個社交型別的產品,所以每個服務請求處理都是響應一次使用者服務請求,所以日誌公共欄位中要求必須加入相應的服務使用者的 ID。
2.2 Console
Console 是日誌系統的控制中心,用於設定服務對應的 LogKafka 叢集編號以及 Kafka 地址,其 UI 介面如下:
上面 UI 中 “叢集編號” 即為 LogKafka 的群集編號。
上面 UI 中 “http協議topics” 設定了某個 “kafka地址” 可以接收的客戶端日誌服務名稱。
上面 UI 中 “udp協議topics” 設定了某個 “kafka地址” 可以接收的服務端日誌服務名稱。
每個服務單獨使用一個 Kafka Topic 通道,Topic 名稱與服務名稱相同。
Console 的資料除存入 Mysql 中作備份外,另外存入註冊中心中,以方便各個服務獲取相關對映資訊。
從上面相關資訊可知:
- 1 一個 LogKafka 群集只對應一個 Kafka 叢集,多個 LogKafka 群集可以共用一個 Kafka 叢集;
- 2 每個服務通道只能通過一個 Kafka 叢集。
2.3 Log Agent
Log Agent 分佈在每個服務節點上,通過監聽 Unix Domain Socket 接收部署在本節點上各個服務的日誌資料,其詳細工作流程如下:
LogAgent 向 LogKafka 傳送日誌資料時採用以 UDP 通訊形式,以方便跨叢集資料傳輸,另一個考量是日誌系統是一種有損服務,即便一段時間內丟若干條日誌資料亦無妨。
Log Agent 收到 UDS 日誌資料包時會解析出 BizType(服務名稱),並根據 BizType 對應的 Log Kafka 叢集資訊以雜湊路由方式固定地向叢集中某一 Log Kafka 傳送日誌。
最終實現的 Log Agent 系統有一個 Service Agent 機制:定時向 Log Kafka 發起 HTTP 請求並讀取其響應,獲取 Log Kafka 節點列表。以及時對 Log Kafka 進行服務發現。
2.3 Log Kafka
Log Kafka 從 Log Agent 接收日誌資料包,進行解析後根據服務名稱寫入相應的 Kafka 傳輸通道。日誌系統中 Log Kafka 以多群集方式進行部署,每個群集都有唯一標識,即 Console UI 介面中的 “叢集編號”。
總體架構圖中 LKC 即為 Log Kafka Cluster 的英文首字母縮寫。
其工作流程如下:
Log Kafka 需要向註冊中心其所在的 Log Kafka 群集的資訊節點進行註冊。
Log Kafka 向其所在的 “叢集編號” 在註冊中心的節點(Zookeeper中的路徑 或者 etcd 的 key等等)註冊完畢後,即可從註冊中心讀取所有 Log Kafka 群集的各個成員資訊。
Log Kafka 根據 Console 在註冊中心儲存的服務對應的各個服務對應的 “叢集編號” 即可知道各個 Log Kafka 群集所傳輸的日誌資料的服務名稱集合【即 ServiceName 到 各個 LogKafka 群集的對映】,根據自身所在群集的 “叢集編號” 亦可得知其可以傳輸的日誌資料的服務名稱集合。
Log Kafka 提供 HTTP 介面,Log Agent可通過這個 HTTP 介面獲取所有的 ServiceName 與 各個 LogKafka 群集的對映資料,以及各個 Log Kafka 群集(LKC)內成員列表。
2.4 Kafka Connector
Kafka Connector 是日誌系統中日誌資料的遷移通道,把不同服務的日誌資料寫入不同的 Elasticsearch 資料庫(Index)中。
Kafka Connector 自身呼叫 Kafka 和 Elasticsearch 的相關 API 即可完成相關功能,然為效率計,最好採用流水線工作模式,不同的服務啟動不同的工作執行緒。
考慮到 Elasticsearch 自身的特點,同一個服務的日誌資料以日為維度進行分庫。
Kafka Connector 同時可以根據 Console 相應配置把 Log Data 寫入 HDFS 中,以方便大資料部門進一步清洗加工處理。
2.5 Es Log Server
Es Log Server 是一個 Web Server,提供日誌資料的查詢和過濾功能,響應對 Log View 發來的請求。
最終的系統實現採用 Python Flask 框架實現相應的功能,因為考慮到日誌系統的寫多讀少特性,Es Log Server並無很高的效能追求。
2.4 Log View
Log View 可以認作是 Es Log Server 的前端展示,採用 Js 實現,其 UI 介面如下:
Es Log Server 和 Log View 系統是愚人用了兩天時間搭建的一個簡單的日誌資料查詢展示系統,實際還有很多進一步的工作待作,不過目前的簡陋實現已經能夠滿足服務端人員的需求。其實另一個不足為外人道的理由是愚人的 Python 和 Js 開發水平是入門級。
3 客戶端日誌收集處理
客戶端日誌整體處理流程與服務端日誌處理流程無差,其區別主要在於日誌 schema 差異甚大,另外還有一個額外的 客戶端日誌上傳機制。
3.1 客戶端日誌格式
同服務端日誌收集一樣,但為了便於日誌收集,客戶端日誌約定了如下共同的日誌欄位(Log Data Common Field)以便於日誌資料清洗和傳輸:
{ “IP”: “10.10.10.10“, “Timestamp”: “20181125 20:56:32.112+08:00”, “DeviceID”: “abcd”, “BizType”: “Recharge”, “BizAction”: “MsgAck”, “UserID”: 456789, “Log”: “xxx” }
各個欄位詳細意義如下:
- 1 IP: Host IP;
- 2 Timestamp: Log Data timestamp;
- 3 DeviceID: 裝置指紋;
- 4 BizType: Service Name,服務名稱,類似於 Class Name;
- 5 BizAction: Service Action,類似於 Class Method;
- 6 UserID: 使用者 ID;
- 7 Log: 其他Log Data,統一放入這個欄位中,用於大資料系統詳細分析處理。
其實客戶端日誌共同欄位同服務端日誌差異不大。BizType 是日誌的行為型別,日誌伺服器會這個欄位把日誌寫入同名的 Kafka Topic。
3.2 客戶端日誌上傳機制
客戶端須通過 HTTP 通道進行明文的日誌傳輸,可啟用壓縮機制,但不能加密,以讓使用者明確知曉 APP 的行為。
客戶端日誌有多種種類,針對不同種類的日誌需要進行不同的上傳機制。即便是同類型日誌,不同版本的客戶端使用者可能需要不同的上傳機制。不同業務隨著業務發展也需要改進上傳機制。
日誌上傳的時候需要對上傳的頻度、檔案size以及上傳渠道(移動 或者 wifi)進行控制。不能頻繁上傳消耗使用者流量和電量,更不能佔用過多系統資源影響使用者體驗。
客戶端通過配置介面(Log Kafka HTTP介面)拉取客戶端日誌配置後,根據配置決定需要上傳的日誌,根據配置決定不同日誌上傳時長間隔。
3.2.1 客戶端日誌上傳配置
愚人定義的客戶端日誌上傳配置規範如下:
{ “version” : 1, “author”: “zx”, “max_size” : 256, “ttl”: 3600, “action”:{ “0”: {“size”: 0, “ttl”:0, “net”: 1}, “1”: {“size”: 8, “ttl”:1, “net”: 3}, “2”: {“size”: 256, “ttl”:600, “net”: 2}, }, “switch”:{ “1” : “1”, “2” : “0”, “3” : “1”, “4” : “1” } }
各個欄位詳細意義如下:
action
上傳動作型別 action
各個欄位詳細意義如下:
- 1 size 是配置檔案的size,以KB為單位;
- 2 ttl 是日誌在客戶端停留時長,超過則不予上傳,以分鐘為單位。0表示不上傳,1意為實時上傳;
- 3 net 是上傳網路通道,0x1 表示無線,0x2 表示wifi,0x3 就表示兩者皆可。
上面示例中,各個 action
意義如下:
編號 | 說明 |
---|---|
0 | 表示不上傳 |
1 | 表示實時上傳,但是size不得超過8KB |
2 | 表示離線上傳,但是檔案size不得超過256KB,日誌內部應該在10小時以內 |
上面示例中,各個上傳行為開關 switch
日誌分類定義如下:
編號 | 說明 |
---|---|
1 | 使用者行為日誌 |
2 | 後臺操作日誌 |
3 | 後臺操作異常/失敗日誌 |
4 | crash日誌 |
3.2.2 客戶端日誌存放刪除規則
客戶端日誌路徑應為 /com.test.xxx/logs/biztype/timestamp
,其中 biztype
為日誌分類名稱, timestamp
為檔案建立時間。
客戶端以log size對log進行分割,日誌刪除規則如下:
- 1 使用者裝置空間餘量不夠;
- 2 日誌過期;
- 3 日誌上傳成功;
3.2.2 客戶端日誌上傳規則
客戶端日誌上傳上傳條件為:應用執行在前臺,網路(移動 或者 wifi)連通,有滿足配置規則的日誌。
上傳詳細流程:
- 1 過濾上傳內容,只上傳 ttl 內的日誌;
- 2 客戶端通過網路通道向日志伺服器上傳日誌;
- 3 收到日誌伺服器返回的上傳結果;
- 4 如果上傳成功則立即刪除 log 檔案,如果上傳失敗無論何種 log 全部轉為離線日誌繼續上傳。
3.3 Log Kafka
客戶端日誌系統所使用的 Log Kafka 叢集與服務端使用的 Log Kafka 叢集分離。
客戶端 Log Kafka 群集 前面有一個 Nginx 叢集,Nginx 叢集配置統一的對外服務域名。由 Nginx 的額外實現邏輯完成對 APP 鑑權工作,然後把日誌資料或者 APP 拉取配置規範請求轉發給 Log Kafka 群集。
Log Kafka 對 APP 的響應亦由 Nginx 原路由轉回。
4 展望
本文詳細記述了愚人實現的日誌系統的相關流程,其實現距今已經半年有餘,有待改進的工作如下:
- 1 與實時監控系統結合,待告警時把相關上下文日誌一併郵件抄送;
- 2 日誌深加工處理,以支撐起鏈路跟蹤系統;
- 3 其他。
參考文件
NULL
扒糞者-於雨氏
2018/11/25,於雨氏,於豐臺,初作此文。