[阿里雲][日誌服務][數據加工][數據分析]基於日誌服務數據加工分析Java異常日誌

1. 本文要點(regex_findall()、e_regex()、e_output()專題):

  • 正則解析複雜異常日誌(一次性解析不出全部格式異常日誌怎麼辦?)
  • 根據不同產品的Exception做數據清洗以及多目標分發
  • 對不同的產品的異常日誌做數據分析

2. 背景

業務背景:
採集並脫敏了整個5月份的項目異常日誌,準備使用日誌服務數據加工做數據清洗以及分析。本案例是基於使用阿里雲相關產品(OSS,RDS,SLS等)的SDK展開自身業務。
業務需求:
需要對異常日誌做解析,將原始日誌中時間、錯誤碼、錯誤信息、狀態碼、產品信息、請求方法、出錯行號提取出來。然後根據提取出來的不同產品信息做多目標分發處理。對清洗後的數據做異常日誌數據分析。

3. 案例總體流程

本案例中的所有異常日誌全部是通過使用日誌服務SDK上傳到cloud_product_error_log的logstore中,然後再經過數據加工清洗數據後投遞到各自產品的logstore中,最後針對各個產品的異常日誌做分析。具體流程如下:
undefined

4. 原始日誌樣例

undefined
原始日誌中只有錯誤日誌信息message,需要將其message中的一些重要信息解析出來。

5. 加工需求

(1) 將message錯誤信息中的時間、錯誤碼、狀態碼、產品信息、錯誤碼信息、請求方法、出錯行號提取出來
(2) 根據提取出的產品信息對清洗後的數據進行多目標分發

具體需求流程如下圖所示:
undefined

6. 對異常日誌數據進行解析和投遞

6.1 加工邏輯分析

下圖展示的是如何從原始異常日誌經過數據加工得到解析後的日誌信息(原始日誌形式,預期日誌形式),然後投遞到不同logstore中,最後對不同產品的異常日誌做數據分析。本案例中只對SLS異常日誌和OSS異常日誌做加工分析。
undefined

6.2 加工操作

經過以上對異常日誌的分析以及加工流程的剖析,此時我們可以對異常日誌加工進行實操(對於不熟悉如何使用日誌服務數據加工的同學可以參考基於日誌服務(SLS)實現電商數據加工與分析)。以下是具體的加工語法:

e_switch(
	regex_match(v("message"), r"LogException"),e_compose(e_regex("message", "(?P<data_time>\S+\s\S+)\s(?P<error_code>[a-zA-Z]+)\s(?P<status>[0-9]+)\scom\.aliyun\.openservices\.log\.exception\.(?P<product_exception>[a-zA-Z]+)\:(?P<error_message>[a-zA-Z0-9:,\-\s]+)\.(\s+\S+\s\S+){5}\s+\S+\scom\.aliyun\.openservices\.log\.Client\.(?P<method>[a-zA-Z]+)\S+\s+\S+\stransformEvent\.main\(transformEvent\.java\:(?P<error_line>[0-9]+)\)"),e_drop_fields("message"),e_output("sls-error")),
	regex_match(v("message"), r"OSSException"),e_compose(e_regex("message", "(?P<data_time>\S+\s\S+)\scom\.aliyun\.oss\.(?P<product_exception>[a-zA-Z]+)\:(?P<error_message>[a-zA-Z0-9,\s]+)\.\n\[ErrorCode\]\:\s(?P<error_code>[a-zA-Z]+)\n\[RequestId\]\:\s(?P<request_id>[a-zA-Z0-9]+)\n\[HostId\]\:\s(?P<host_id>[a-zA-Z-.]+)\n\S+\n\S+(\s\S+){3}\n\s+\S+\s+(.+)(\s+\S+){24}\scom\.aliyun\.oss\.OSSClient\.(?P<method>[a-zA-Z]+)\S+\s+\S+\stransformEvent\.main\(transformEvent\.java:(?P<error_line>[0-9]+)\)"),e_drop_fields("message"),e_output("oss-error"))
)

點擊預覽效果如下所示:
undefined
上圖表面加工語法能夠正常解析異常日誌,接下來需要進行保存加工任務操作。具體加工配置如下圖:
undefined
注意:
以上語法中的e_output中的name參數需要與加工配置規則中的目標名稱一一對應。更多用法請參考e_output語法注意事項

6.3 語法詳解

其中涉及到的正則語法分組相關知識請移步正則表達式-分組
(1) 首先使用regex_match函數匹配出此條日誌中是否有LogException如果匹配上則走解析sls異常日誌的規則分支,如果匹配上OSSException則走解析OSS異常日誌的規則分支。
(2) 其次使用e_regex正則解析函數解析相應的異常日誌。
(3) 最後刪除原字段message信息,並投遞到相應產品的logstore中。

其中本案例中正則解析日誌詳解是以解析SLS異常日誌爲例,具體如下
undefined

7. 數據加工診斷

當我們在解析日誌的時候,時常會遇到一次性解析不出全部格式異常日誌的情況。並且在加工預覽頁面只會預覽一定量的數據,因此在加工預覽頁面不一定會提示出該正則解析不出的日誌的情況。
綜上,我們可以通過查看數據加工概覽(具體如何查看請參考加工概覽)的方式查到具體是那一條日誌沒有解析出來,然後再調整我們的正則表達式。解析失敗樣例,如下圖所示:
undefined
具體異常詳情的logging如下:

{
    "message": "transform_regex: field value \"2020-05-04 08:45:07 ServerBusy 505 com.aliyun.openservices.log.exception.LogException:The server is busy, please try again later.\n    at com.aliyun.openservices.log.Client.ErrorCheck(Client.java:2161)\n    at com.aliyun.openservices.log.Client.SendData(Client.java:2312)\n    at com.aliyun.openservices.log.Client.CreateConsumerGroup(Client.java:2190)\n    at com.aliyun.openservices.log.Client.SendData(Client.java:2265)\n    at com.aliyun.openservices.log.Client.GetCursor(Client.java:1123)\n    at com.aliyun.openservices.log.Client.CreateConsumerGroup(Client.java:1100)\n    at transformEvent.main(transformEvent.java:1950)\" cannot extract value with config \"(?P<data_time>\\S+\\s\\S+)\\s(?P<error_code>[a-zA-Z]+)\\s(?P<status>[0-9]+)\\scom\\.aliyun\\.openservices\\.log\\.exception\\.(?P<__topic__>[a-zA-Z]+)\\:(?P<error_message>[a-zA-Z0-9\\s:-]+)\\.(\\s+\\S+\\s\\S+){5}\\s+\\S+\\scom\\.aliyun\\.openservices\\.log\\.Client\\.(?P<method>[a-zA-Z]+)\\S+\\s+\\S+\\stransformEvent\\.main\\(transformEvent\\.java\\:(?P<error_line>[0-9]+)\\)\"",
    "processName": "MainProcess",
    "process": "1",
    "thread": "139873923098368",
    "levelname": "WARNING",
    "module": "regex_impl",
    "threadName": "ThreadPoolExecutor-0_1",
    "funcName": "__call__"
}

從以上圖例和具體信息可以看到,如果正則解析失敗會報WARNING級別日誌。此時的加工處理規則是跳過加工失敗的日誌繼續往下加工,此過程中並不會影響到整個加工任務的執行(只有ERROR級別的會影響到整個加工任務的消費)。
接下來主要關注message中的日誌信息,看具體是那條日誌或者那一類異常日誌導致現有的正則規則加工失敗。
其message中的解析失敗的日誌和正則(logging中的正則表達式需要自己去掉多加的轉義反斜槓)。

"""解析失敗日誌"""
2020-05-04 08:45:07 ServerBusy 505 com.aliyun.openservices.log.exception.LogException:The server is busy, please try again later.\n    at com.aliyun.openservices.log.Client.ErrorCheck(Client.java:2161)\n    at com.aliyun.openservices.log.Client.SendData(Client.java:2312)\n    at com.aliyun.openservices.log.Client.CreateConsumerGroup(Client.java:2190)\n    at com.aliyun.openservices.log.Client.SendData(Client.java:2265)\n    at com.aliyun.openservices.log.Client.GetCursor(Client.java:1123)\n    at com.aliyun.openservices.log.Client.CreateConsumerGroup(Client.java:1100)\n    at transformEvent.main(transformEvent.java:1950)
"""正則表達式"""
(?P<data_time>\S+\s\S+)\s(?P<error_code>[a-zA-Z]+)\s(?P<status>[0-9]+)\scom\.aliyun\.openservices\.log\.exception\.(?P<product_exception>[a-zA-Z]+)\:(?P<error_message>[a-zA-Z0-9\s:-]+)\.(\s+\S+\s\S+){5}\s+\S+\scom\.aliyun\.openservices\.log\.Client\.(?P<method>[a-zA-Z]+)\S+\s+\S+\stransformEvent\.main\(transformEvent\.java\:(?P<error_line>[0-9]+)\)

經過一步一步的查找驗證,得出在解析error_message中缺少了對有逗號情景的解析,因此此地方正則需要改善,具體改善如下:

"""解析失敗error_message正則"""
(?P<error_message>[a-zA-Z0-9\s:-]+)
"""完善後解析error_message正則"""
(?P<error_message>[a-zA-Z0-9:,\-\s]+)

綜上,經過我們不斷的完善正則表達式,目前是能夠成功解析各個不同類型的異常日誌。接下來我們將進入數據分析階段。

8. 異常日誌數據分析

下圖是通過sql查詢所展示數據儀表大盤:
undefined
基於加工後的異常日誌(以SLS錯誤日誌爲例分析),在這裏我們的需求有以下幾方面:
(1) 各個方法異常統計
(2) 各個方法異常佔比統計圖
(3) PutLogs錯誤信息
(4) 各個方法調用報錯每日level氣泡圖
(5) 各個ErrorCode統計分析
(6) 各個方法報錯時間軸

8.1 各個方法異常統計和各個方法異常佔比統計圖

爲了方便查看那個方法出現錯誤次數最高和幫助我們定位業務調用的具體方法,因此我們先對各個方法出現的異常情況做一個統計。

* | SELECT COUNT(method) as m_ct, method GROUP BY method

這條語句表示的是統計每個調用方法出現異常的數量。
下圖表示的是在查詢框裏輸入以上sql分析語句之後進入統計圖表,然後點擊條形圖進行配置,method爲X軸,m_ct爲Y軸。
undefined
通過上圖分析可知總體情況,PutLogs調用出現異常的次數最多,其中GetCursor和DeleteConsumerGroup是出現異常的次數是最少的。
此外,爲了方便我們查看各個方法異常佔比情況,我們可以基於以上的SQL做一個佔比統計圖,點擊漏斗圖,然後以method爲分組列,m_ct爲數值列具體操作如下。
undefined

8.2 PutLogs錯誤信息

爲了方便我們查看哪一類的錯誤信息是佔比最大,幫助我們分析:
(1) 需要自身業務需要改進的
(2) 需要SLS幫忙調整的(如調整quota)
(3) 需要深入項目中具體排查錯誤的(具體的error line)

* | SELECT error_message,COUNT(error_message) as ct_msg, method WHERE method LIKE 'PutLogs' GROUP BY error_message,method

點擊矩形樹圖,然後以error_message爲分類和ct_msg爲數值列。
undefined
從上圖中我們可知:
(1) consumer group already exist、consumer group not exist、Logs must be less than or equal to 3 MB and 4096 entries等這些都是屬於需要在項目中具體排查的錯誤
(2) Read/ Write quota is exceeded這些是需要SLS調整quota的
(3) 還有一些是需要調整自身業務的比如logstore/ project not exist看是否是因爲一些業務原因而導致這些project被取消等等。

8.3 各個方法調用報錯每日level氣泡圖

爲了方面我們查看每一天的各個調用方法出錯頻次,我們需要有一個直觀的圖來查看每一天的調用出錯程度,這樣我們可以更加直觀的去看某一天的具體調用出錯細節。

* | select date_format(data_time, '%Y-%m-%d') as day,COUNT(method) as count_method, case 
when method = 'PullLogs' and COUNT(method) > 21800 then 3 when method = 'PullLogs' and COUNT(method)>21400 then 2 when method = 'PullLogs' and COUNT(method)>21100 then 1 
when method = 'CreateConsumerGroup' and COUNT(method) > 21900 then 3
when method = 'CreateConsumerGroup' and COUNT(method) > 21700 then 2 when method = 'CreateConsumerGroup' and COUNT(method) > 21550 then 1 
when method = 'PutLogs' and COUNT(method)>43900 then 3 when method = 'PutLogs' and COUNT(method)>43300 then 2 when method = 'PutLogs' and COUNT(method)>42900 then 1 
when method = 'DeleteConsumerGroup' and COUNT(method)>7440 then 3 when method = 'DeleteConsumerGroup' and COUNT(method)>7330 then 2 when method = 'DeleteConsumerGroup' and COUNT(method)>7320 then 1 
when method = 'GetCursor' and COUNT(method)>7350 then 3 when method = 'GetCursor' and COUNT(method)>7200 then 2 when method = 'GetCursor' and COUNT(method)>7150 then 1
else 0 end as level,  method group by day, method ORDER BY day asc

其中如果一天PullLogs出錯次數大於21800則屬於level3級別的,大於21400則屬於level2級別,大於21100則屬於level1,否則屬於level0,然後再跟據每一天每個方法做聚合操作。
點擊氣泡圖,其中以day爲X軸,method爲Y軸。
undefined
從上圖中可以明顯的知道每一天的每個方法的出現異常的level值,針對某一天level值高的可以對其做具體的錯誤查看到底是什麼原因引起的。

8.4 各個ErrorCode統計分析

統計各個error_code出現的錯誤次數,能夠更好的幫助我們查看哪些是因爲ServerBusy,哪些是因爲ParameterInvalid等不同的原因引起的異常,從而更好的定位異常原因。

* | SELECT error_code,COUNT(error_code) as count_code GROUP BY error_code

點擊折線圖,以error_code爲X軸,以count_code爲Y軸
undefined
基於上圖可知WriteQuotaExceed出現異常次數最多,可以查查那個project下的logstore被限制,然後諮詢相關的產品技術支持。

8.5 各個方法報錯時間軸

設置報錯時間軸,可以實時的查看調用接口異常信息。

* | SELECT date_format(data_time, '%Y-%m-%d %H:%m:%s') as date_time,status,product_exception,error_line, error_message,method ORDER BY date_time desc

undefined
基於上圖所示,我們可以對重要的接口出現異常做標註高亮顯示,以便我們能夠快速識別出重要接口異常情況。

9. 總結

對於其他的產品的異常日誌,我們也可以使用同樣的方法加工清洗投遞,然後SQL分析自己所關心的業務指標。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章