作者:太業
流式處理語言發展
-
早期流式處理概念:
- 20 世紀 70 年代,程式語言如 APL 提供了對陣列的流式操作,這可以看作是流式處理語法的早期形式。
- 管道(Pipes)概念在 UNIX 系統中的引進使得可以透過命令列將一個命令的輸出串聯到另一個命令的輸入。
-
Java 的流(Stream)API:
- Java 8 在 2014 年引入了 Stream API,為集合框架提供了一套流式處理語法。
- Stream API 支援鏈式呼叫、延遲計算和內部迭代,使得流式處理與 Java 語言天然融合。
-
分散式流處理框架:
- Apache Storm 和 Apache Samza 等框架提供了面向分散式流處理的語言和 API。
- Apache Flink 和 Apache Beam 等更現代化的框架引入了支援事件時間(event time)概念和視窗化計算的複雜流式處理語法。
-
流批一體(Stream-Batch Unification):
- Apache Beam 推廣了一種新的模型,它允許開發者以相同的方式處理批處理和流處理。
- 這一模型透過提供一套統一的流式處理語法和抽象,簡化了在不同執行時(如Flink、Google Cloud Dataflow)上編寫資料處理管道的過程。
-
SQL 流式查詢語言:
- 流式 SQL 查詢語言的發展,如 Apache Flink 的SQL API 和 KSQL(Kafka Streams 的 SQL 介面),使得使用者可以透過類 SQL 語法編寫複雜的流式處理邏輯。
日誌與時序資料屬於典型的半結構化或者弱結構化資料,在此基礎上微軟推出了 KQL(Kusto Query Language)、 Splunk 推出了 Splunk Processing Language,他們都有如下特點:
-
直觀的資料搜尋和探索:
- 使使用者能夠透過簡單的搜尋語法直接查詢資料,類似於如何在搜尋引擎中查詢資訊。
-
強大的資料處理能力:
- 考慮到了需要在大資料集上執行復雜的資料處理和轉換操作,例如統計計算、資料分組和排序。
-
靈活的資料分析:
- 提供了多種命令和函式,使使用者可以靈活地分析資料,包括對時間序列資料進行視覺化、識別模式和異常以及建立複雜的資料關聯。
-
實時和歷史資料處理:
- 能夠處理實時資料流和歷史資料儲存,使得使用者能夠進行即時監控以及過去事件的分析。
-
可擴充套件性:
- 允許使用者建立自定義搜尋命令和指令碼,從而擴充套件語法的功能,使其能夠滿足特定的業務需求。
-
易於學習和使用:
- 設計注重於易用性,意味著即使是非技術使用者也能夠透過簡單的查詢和命令來分析資料。
在此背景下,SLS 推出了 SPL(SLS Processing Language)語法,以此統一查詢、端上處理、資料加工等的語法,保證了資料處理的靈活性。iLogtail 作為日誌、時序資料採集器,在 2.0 版本中,全面支援了 SPL 。
SPL 和 iLogtail Pipeline 模式的對比
在支援 SPL 之前,iLogtail 在做資料解析的時候,使用的是 Pipeline 模式。
iLogtail 1.X Pipeline 模式
從整體來看,iLogtail 的檔案採集模式可以劃分為以下兩種:
原生外掛解析模式
如上圖中間部分所示,純 iLogtail 的核心處理部分由日誌切分(Splitter)和日誌解析(Parser)組成,均由 C++ 實現,根據選擇的日誌採集模式,日誌切分把讀取的檔案內容切割成為一條條日誌(比如單行基於換行符、多行基於行首正則),然後交由日誌解析從單條日誌中提取欄位。僅能支援正則、Json 和分隔符模式等固定模式 [ 1] ,且無法自由組合。這種基於採集模式的解析,擁有更好的效能,但犧牲了靈活性。
擴充外掛 Pipeline 模式
在擴充外掛模式下,iLogtail 會將日誌切分的結果直接提交給 Golang 外掛模組進行處理,在後者中,我們可以組合多種處理外掛 [ 2] ,來滿足我們的需求。擴充外掛模式則是犧牲一定的效能和計算資源來換取靈活性,以應對更為複雜的場景。
iLogtail 1.X Pipeline 模式的侷限
靈活性和效能只能二選一
- 原生外掛模式效能最強,但是支援的格式有限。
- 擴充外掛模式靈活性足夠,但是資源消耗變大、效能有損耗。
- 引入 Golang 外掛之後,C++ 到 Golang 外掛跨語言傳遞資料,會引入額外的序列化與反序列化的步驟,帶來一定的效能下降。
- Golang 相關解析函式的效能,還是要比 C++ 的低。
條件判斷
iLogtail 外掛的配置,還是更加適合格式比較固定格式日誌的處理與解析。如果日誌格式比較多樣,單一的 Pipeline 是很難處理的,則需要配置多個 Pipeline。
配置簡便性
iLogtail 控制檯採集配置頁面對每個外掛都有對應的配置模組,想要做複雜的配置,頁面上的互動還是會比較繁瑣。
iLogtail2.0 + SPL
那麼有沒有一種方案,可以實現既要效能,又要靈活性呢?ilLogtail2.0 帶著 SPL 一起來了。
iLogtail 2.0 中,SPL 是跟 Pipeline 並列的一個實現,底層呼叫了 SLS 統一的 SPL Lib,由此可以使用 SPL 完整的處理能力。
從 SLS 控制檯可以看到 SPL 模式和 Pipeline 模式屬於同級配置,兩種模式可以選一種進行使用。
SPL 語法簡介
語法結構
- 指令式語句,支援結構化資料和非結構化資料統一處理
- 管道符(|)引導的探索式語法,複雜邏輯編排簡便
<data-source>
| <spl-cmd> -option=<option> -option ... <expression>, ... as <output>, ...
| <spl-cmd> ...
| <spl-cmd> ...
結構化資料 SQL 計算指令
- extend 透過 SQL 表示式計算結果產生新欄位
- where 根據 SQL 表示式計算結果過濾資料條目
*
| extend latency=cast(latency as BIGINT)
| where status='200' AND latency>100
欄位操作指令
- project 保留與給定模式相匹配的欄位、重新命名指定欄位
- project-away 移除與給定模式相匹配的欄位,原樣保留其他所有欄位
- project-rename 重新命名指定欄位,並原樣保留其他所有欄位
*
| project-away -wildcard "__tag__:*"
| project-rename __source__=remote_addr
非結構化資料提取指令
- parse-regexp 提取指定欄位中的正規表示式分組匹配資訊
- parse-json 提取指定欄位中的第一層 JSON 資訊
- parse-csv 提取指定欄位中的 CSV 格式資訊
*
| project-csv -delim='^_^' content as time, body
| project-regexp body, '(\S+)\s+(\w+)' as msg, user
iLogtail2.0 + SPL 的優勢
SPL 語法全域性統一
比如原來同樣一個格式的資料,資料加工和 iLogtail 採集的配置是完全不同的,可能會導致客戶需要有兩個配置。現在 SPL 語法統一之後,同樣的配置基本可以無縫在 iLogtail 和實時消費中轉換。
C++ 原生高效能處理能力
SPL 的核心運算元,都是 C++ 實現的,效能能夠接近 iLogtail 原生 C++ 外掛的效能,遠高於 Logtail 擴充外掛的效能。
豐富的函式支援
SPL 目前支援的函式已經全面對齊 SLS SQL 語法的函式。(SPL 支援的函式列表 [ 3] )
上手簡單,除錯方便
自動識別當前所處的語法模式,並對 SPL 相關指令和函式進行智慧提示:
iLogtail 採集配置頁面支援 SPL 預覽,方便上手除錯,可以實時看到配置效果:
iLogtail2.0+SPL 實戰
下面我們透過一個實際的例子來體驗一下。
SPL 配置入門
如下是一條混合了 json 和 java 堆疊資訊的樣例日誌:
[2024-01-05T12:07:00.123456] {"message": "this is a msg", "level": "INFO", "garbage": "xxx"} java.lang.Exception: exception發生
at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f3(RegexMultiLog.java:130)
at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f2(RegexMultiLog.java:125)
at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.f1(RegexMultiLog.java:118)
at com.aliyun.sls.devops.logGenerator.type.RegexMultiLog.run(RegexMultiLog.java:70)
at java.base/java.lang.Thread.run(Thread.java:833)
我們先來看下 iLogtail 外掛模式是如何配置的:
- 開啟多行模式,配置行首正規表示式
- 依次配置 Processor 外掛
我們先用正則解析外掛將原始日誌分割成三個欄位:time,json 和 stack:
然後配置 Json 解析外掛,將 json 欄位解析開:
最後配置丟棄欄位外掛,將不需要的欄位丟棄:
然後我們再來看下 SPL 是如何配置的。
透過上面的步驟分析,我們發現這個解析過程拆解到 SPL 中可以使用如下配置。
第一步是正則解析,從原始欄位中透過正規表示式,解析出 time, json 和 stack 三個欄位:
parse-regexp content, '[([^]]+)]\s+([^}]+})\s+(.*)' as time,json,stack
第二步是 json 解析,從 json 欄位中解析出 level,message 和 garbage 欄位:
parse-json json
第三步是丟棄欄位:
project-away garbage,json
這裡需要注意的是,parse-json,parse-regexp 解析成功之後,是不丟棄原始的欄位的,因此如果最後的資料中不需要原始欄位,那麼需要主動刪除一下原始欄位。
將上面的語句用管道符號連線起來,就得到了完整的 SPL 語句:
* | parse-regexp content, '[([^]]+)]\s+([^}]+})\s+(.*)' as time,json,stack | parse-json json | project-away garbage,json,content
最終配置如下圖所示:
-
開啟多行模式,配置行首正規表示式
-
處理模式選擇 SPL,填入 SPL 語句
從控制檯互動上看,SPL 配置的互動更加簡便,不需要一個外掛一個外掛配置。
SPL 除錯利器- SPL 配置效果預覽
針對 SPL 的配置,控制檯還提供了樣例日誌實時預覽 SPL 處理結果的功能,新增日誌樣例之後,點選預覽按鈕,就是可以看到當前 SPL 語句的處理結果,可以非常方便的進行除錯和最佳化。
繼續用上面的例子,我們可以一步一步看到 SPL 配置的效果:
第一步是正則解析:
parse-regexp content, '[([^]]+)]\s+([^}]+})\s+(.*)' as time,json,stack
可以看到資料被分割成了 time、json 和 stack 三個欄位,原始欄位 content 仍然保留著。
然後我們把 json 解析也加上,繼續看下效果:
parse-regexp content, '[([^]]+)]\s+([^}]+})\s+(.*)' as time,json,stack | parse-json json
可以看到 json 欄位也被解析出來了,得到了 message,level 和 garbage 欄位,同時 json 欄位也被保留下來。到這裡,所有欄位解析都完成了,最後,我們就刪除掉一些我們不需要的欄位就好了。
* | parse-regexp content, '[([^]]+)]\s+([^}]+})\s+(.*)' as time,json,stack | parse-json json | project-away garbage,json,content
可以看到,garbage,json 和 content 欄位都被刪除了,整個過程非常輕鬆和高效。
開源 iLogtail 配置實踐
開源的 iLogtail 配置 SPL 也是非常簡單的,如下就是一個 SPL 配置的例項:
enable: true
inputs:
- Type: input_file
FilePaths:
- /home/test-log/test.log
Multiline:
StartPattern: \[\d+.*
processors:
- Type: processor_spl
Script: '* | parse-regexp content, ''\[([^]]+)]\s+([^}]+})\s+(.*)'' as time,json,stack | parse-json json | project-away garbage,json,content'
flushers:
- Type: flusher_stdout
OnlyStdout: true
模擬資料寫入:
可以看到資料已經被正確的解析出來了:
總結
日誌資料格式可能是多樣且複雜的,iLogtail 外掛配置模式已經可以很好的支援複雜資料的處理。iLogtail2.0 又帶來了 SPL 語法的重大支援,在日誌處理場景下,可以透過多級管道對資料進行互動式、遞進式的探索和處理,從配置互動和效能上,都有比較大的提升和最佳化。
iLogtail2.0 已經在逐步灰度中,歡迎大家體驗和使用。
相關連結:
[1] 原生外掛
https://help.aliyun.com/zh/sls/user-guide/native-plug-ins/?spm=a2c4g.11174283.0.0.65e95c0dTnOzh8
[2] 擴充套件外掛
https://help.aliyun.com/zh/sls/user-guide/extension-plug-in/?spm=a2c4g.11186623.0.0.4bed5c0dYhtlZp
[3] SPL 支援的函式列表
https://help.aliyun.com/zh/sls/user-guide/function-overview