• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • Logtail 混合模式:使用插件處理文件日志

    標簽: 插件系統  性能  正則表達式

    作為一個服務百萬機器的日志采集 agent,Logtail 目前已經提供了包括日志切分、日志解析(完整正則、JSON、分隔符)、日志過濾在內的常見處理功能,能夠應對絕大多數場景的處理需求。但有些時候,由于應用的歷史原因或是本身業務日志的復雜性,單一功能可能無法滿足所采集日志的處理需求,比如:

    • 日志可能不再是單一格式,有可能同時由 JSON 或者分隔符日志組成。
    • 日志格式可能也不固定,不同的業務邏輯所產生的日志具有不同的字段。
    • ...

    為此,Logtail 引入了 混合模式,一方面借助 Logtail 完善的事件機制來保證數據讀取階段的可靠性,另一方面,依賴于插件系統豐富的插件,來加強 Logtail 對復雜日志的處理能力。

    Logtail 采集模式劃分

    從整體來看,Logtail 的采集模式可以劃分為以下三種:

    • 純 Logtail 模式:提供文本日志的采集能力,比如 Nginx 日志、JSON 日志、分隔符日志等。
    • 純插件模式:作為文本日志采集的補充,提供對更豐富數據源的采集能力,包括 MySQL Binlog、JDBC Query、Syslog 等,同時還提供了一系列的插件來支撐采集后的數據處理。
    • 混合模式:綜合上述兩者的能力,支持通過插件實現對文本日志的多樣處理。

    混合模式工作原理

    如上圖中間部分所示,純 Logtail 的核心處理部分由日志切分(Splitter)和日志解析(Parser)組成,根據選擇的日志采集模式,日志切分把讀取的文件內容切割成為一條條日志(比如單行基于換行符、多行基于行首正則),然后交由日志解析從單條日志中提取字段。由此可見,日志的采集模式固定了處理行為,比如完整正則模式要求日志必須完全符合設置的正則表達式,否則會報錯。這種基于采集模式的固定行為,擁有更好的性能,但犧牲了靈活性。

    相比之下,混合模式則是犧牲一定的性能和計算資源來換取靈活性,以應對更為復雜的場景。如上圖所示,在混合模式下,Logtail 會將日志切分的結果直接提交給插件進行處理,在后者中,我們可以組合多種處理插件,來滿足我們的需求。

    使用及限制說明

    • 混合模式依舊依賴于 Logtail 完成日志切分,所以對于多行日志,依舊需要配置行首正則。
    • 出于性能考慮,Logtail 提交給插件部分的數據并非是單條日志,而是日志的組合,因此插件處理配置的開始需要配置特定插件進行二次切分,具體下文將介紹。
    • 性能開銷:視配置而定,混合模式下 Logtail 會消耗更多的資源(主要是 CPU)來完成處理任務,因此需要根據實際情況調整 Logtail 的資源限制。如果采集節點的資源有限,但確實有處理需求,可以仍舊使用純 Logtail 模式進行采集,之后使用數據加工來實現數據處理。
    • Logtail 的版本需要在 0.16.28 及以上。
    • 一些文本文件的功能在混合模式下無法使用,包括過濾器配置、上傳原始日志、機器時區、丟棄解析失敗日志、接受部分字段(分隔符模式)等,但其中部分功能可通過相關插件來實現。

    插件處理配置語法

    插件處理配置使用 JSON 對象進行表示,配置的 key 為 processors,value 是 JSON 對象的數組,數組內的每一個 JSON 對象表示一個處理插件的配置,處理時將按照數組內的定義順序依次執行。數組內的每個 JSON 對象包含兩個字段:type 和 detailtype 表示處理插件的類型(JSON string),detail 表示該插件的詳細參數(JSON 對象,key 為參數名,value 為參數值)。

    {
      "processors": [
        {
          "type": "processor_regex",
          "detail": {
            "SourceKey": "content",
            "Regex": "...",
            "Keys": [
              "time",
              "short_msg",
              "main_msg",
            ]
          }
        },
        {
          "type": "processor_regex",
          "detail": {
            "SourceKey": "main_msg",
            "Regex": "...",
            "Keys": [
              ...
            ]
          }
        }
      ]
    }

    如上示例表示使用兩個 processor_regex 插件進行日志處理,第一個插件根據配置的 Regex 參數對日志中的 content 字段進行正則提取,結果為 Keys 參數指定的三個字段,而第二個插件對上一步提取得到的 main_msg 字段再次進行正則提取,得到更多的字段。

    支持的插件列表

    以下是當前所支持的處理插件,關于具體插件如何使用可參考文檔處理采集數據

    插件類型(type) 功能
    processor_add_fields 向日志中添加固定的一些字段
    processor_rename 重命名指定字段名
    processor_drop 根據字段名丟棄日志中的一些字段
    processor_drop_last_key 當日志中存在指定的一些字段(名)時,丟棄特定字段,一般用于解析類型的處理插件后,當存在解析后的字段時,表示解析成功,可以丟棄原始字段
    processor_filter_key_regex 判斷字段名是否符合設置的正則表達式,進而決定是否保留該字段
    processor_filter_regex 判斷字段值是否符合設置的正則表達式,進而決定是否保留該字段
    processor_geoip 對指定字段值(IP)進行地理位置分析,需要自行提供數據庫
    processor_gotime 對指定字段值使用 Go 語言的時間格式進行解析,可將解析結果設置為日志時間
    processor_strptime 對指定字段值使用 strptime 的時間格式進行解析,可將解析結果設置為日志時間
    processor_md5 對指定字段值進行 MD5
    processor_base64_decoding 對指定字段值進行 base64 解碼
    processor_base64_encoding 對指定字段值進行 base64 編碼
    processor_anchor 可以配置 anchor 指定 start/stop 子串,然后對指定字段值進行處理,提取 start/stop 子串之間的內容作為新字段
    processor_regex 對指定字段值進行正則提取
    processor_json 對指定字段值進行 JSON 解析,可將結果展開為日志內容
    processor_packjson 將指定的多個字段以 JSON 對象的格式打包至一個目標字段
    processor_split_char 對指定字段值進行單字符分隔符(支持設置引用符)解析
    processor_split_string 對指定的字段值進行多字符分隔符解析
    processor_split_key_value 對指定的字段值進行鍵值對解析,如飛天日志
    processor_split_log_regex 對指定字段值使用行首正則表達式進行切分,結果將分裂為多條日志,一般用于混合模式下對接 Logtail 多行日志
    processor_split_log_string 對指定字段值使用多字符進行切分,結果將分裂為多條日志,一般用于混合模式下對接 Logtail 單行日志(使用換行符作為分隔)

    使用特定插件完成日志的二次切分

    前文的說明中曾經提到,出于性能考慮,Logtail 提交給插件部分的數據并非是單條日志,而是日志的組合,需要在插件處理配置的開始增加特定插件進行二次切分。

    總的來說,切分時所需要考慮的情況有單行日志和多行日志兩種,以下將分別介紹。

    注意:此配置僅在混合模式下需要,如果使用的純自定義插件的采集配置,可以忽略。

    單行日志

    假設單行日志的內容是 2019-09-23 14:08:16.952 [INFO] hello world,則 Logtail 提交給插件部分的數據內容可能是:

    "content": "2019-09-23 14:08:16.952 [INFO] hello world\n2019-09-23 14:08:16.952 [INFO] hello world1\n2019-09-23 14:08:16.952 [INFO] hello world2"

    可以看到,多條單行日志被一次性輸入到插件處理中,因此,我們需要配置一個針對單行日志的切分插件,即先前列表中最后的 processor_split_log_string。對于單行日志,可以直接復用如下配置:

    {
      "type": "processor_split_log_string",
      "detail": {
        "SplitKey": "content",
        "SplitSep": "\n"
      }
    }

    多行日志

    類似地,多行日志在提交給插件部分時也需要使用 processor_split_log_regex 進行基于行首正則的切分,配置如下(假設日志開頭為常見的 [] 包裹時間):

    {
      "type": "processor_split_log_regex",
      "detail": {
        "SplitKey": "content",
        "SplitRegex": "\\[\\d+-\\d+\\d+\\s\\d+:\\d+:\\d+\\].*"
      }
    }

    參考此配置時需要根據實際情況調整行首正則表達式(SplitRegex)。

    混合模式使用步驟

    1. 根據日志是單行還是多行,確定插件處理配置中需要引入的切分插件及其配置,如果是多行,確認行首正則表達式。
    2. 根據日志的格式組合之前提及的處理插件,完善插件處理配置。
    3. 應用插件處理配置:兩種途徑,API/SDK 或控制臺。

    創建混合模式采集配置

    從先前的介紹中可以看出,混合模式的采集配置實質上是文本模式的采集配置附加上額外的插件處理配置,因此,配置它的入口依舊是創建文本模式的采集配置:如果是單行日志,創建 極簡模式 的采集配置,如果是多行日志,創建 完整正則模式 的采集配置,并切換至多行模式,設置行首正則表達式。

    API/SDK

    在完成文本模式的采集配置創建后,我們可以通過 API/SDK 的方式添加構建好的插件處理配置。此處,我們借助 CLI 來實現這個過程,代碼如下:

    # add_plugin_config.py
    # -*- coding:utf-8 -*-
    
    import commands
    import json
    import os
    import sys
    
    if len(sys.argv) != 4:
        print 'Usage: add_plugin_config.py <your_project_name> <your_config_name> <plugin_config_file>'
        sys.exit(1)
    
    your_project_name = sys.argv[1]
    your_config_name = sys.argv[2]
    your_plugin_config_file = sys.argv[3]
    
    status, output = commands.getstatusoutput(
        'aliyunlog log get_logtail_config --project_name={} --config_name={}'.format(your_project_name, your_config_name))
    if status != 0:
        print '[ERR] can not find specified config, please check your CLI configuration'
        print 'ErrMsg:', output
        sys.exit(1)
    config = json.loads(output)
    print config
    
    plugin = json.load(open(your_plugin_config_file, 'r'))
    config["inputDetail"]["plugin"] = plugin
    with open('logtail_config.json', 'wb') as f:
        f.write(json.dumps(config))
    
    update_cmd = 'aliyunlog log update_logtail_config --project_name="{}" --config_detail="$(cat logtail_config.json)"'.format(your_project_name)
    print update_cmd
    print os.system(update_cmd)

    確定你需要修改的配置所屬的 project_nameconfig_name,把插件處理配置保存到任意文件(比如 plugin_config.json)后,調用腳本傳入這三個參數即可。

    控制臺

    在 SLS 控制臺上,我們可以通過 高級選項-啟用插件處理 來啟用混合模式。

    在 API/SDK 的方式下,我們需要根據所選模式(JSON、分隔符等)來對二次切分的插件進行配置。而在控制臺上使用混合模式時,頁面將會根據所選的模式,自動地生成相應的默認配置,我們只需要配置針對單條日志的處理即可。通過 顯示/隱藏默認配置,我們可以查看插件配置的完整內容。

    以下示例在極簡模式下使用 processor_add_fields 插件為每條日志增加兩個固定的字段。從兩張截圖的區別可以發現,頁面在默認配置中自動地填充了 processor_split_log_string 來實現按行二次切分。

    示例

    原始日志

    假設我們所采集的是單行文本日志,原始日志內容如下:

    "content": "2019-09-23 14:08:16.952 cip>->1.1.1.1_'_sip>->2.2.2.2_'_scheme>->http:POST_'_uri>->/v1/a/b/c_'_rt.all>->21_'_rt.p0>->19_'_\t{\"errcode\":10000,\"errmsg\":\"OK\",\"errdetail\":null,\"data\":{}}"

    該日志由 時間多組鍵值對JSON 對象 三部分組成,分別使用 空格 和 制表符 進行分隔,其中多組鍵值對部分使用 _'_ 分隔鍵值對,>-> 分隔鍵和值。

    預期結果

    為了方便分析,我們希望將日志的內容提取成如下的字段:

    "time": "2019-09-23 14:08:16.952"
    "cip": "1.1.1.1"
    "sip": "2.2.2.2"
    "scheme": "http:POST"
    "uri": "/v1/a/b/c"
    "rt.all": "21"
    "rt.p0": "19"
    "errcode": "10000"
    "errmsg": "OK"
    "errdetail": "null"

    插件處理配置

    {
      "processors": [
        {
          "type": "processor_split_log_string",
          "detail": {
            "SplitKey": "content"
          }
        },
        {
          "type": "processor_regex",
          "detail": {
            "SourceKey": "content",
            "Regex": "(\\d+-\\d+-\\d+\\s\\d+:\\d+:\\d+\\.\\d+)\\s(.*)_'_\t(.*)",
            "Keys": [
              "time",
              "main_msg",
              "json_msg"
            ],
            "NoKeyError": true,
            "NoMatchError": true,
            "KeepSource": true
          }
        },
        {
          "type": "processor_json",
          "detail": {
            "SourceKey": "json_msg",
            "KeepSource": true    
          }
        },
        {
          "type": "processor_split_key_value",
          "detail": {
            "SourceKey": "main_msg",
            "Delimiter": "_'_",
            "Separator": ">->",
            "KeepSource": true
          }
        }
      ]
    }

    如上是我們所創建的混合模式采集配置中的插件處理配置部分,由 4 個處理插件組成:

    • processor_split_log_string:用于完成之前【使用特定插件完成日志的二次切分】提及的日志切分。
    • processor_regex:將日志內容切分為三部分,三個字段分別為 timemain_msgjson_msg
    • processor_json:對上一步提取得到的 json_msg 進行解析,將其中的內容展開為日志字段。
    • processor_split_key_value:對 main_msg 字段進行進一步的解析,將其中的各個鍵值對展開為日志字段。


    原文鏈接
    本文為云棲社區原創內容,未經允許不得轉載。

    版權聲明:本文為yunqiinsight原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/yunqiinsight/article/details/103137441

    智能推薦

    學會看日志文件處理問題

    rsyslog是一個進程,是一個命令。管理日志的。–》系統日志記錄器 它有一個配置文件:/etc/rsyslog.conf 自己創建日志時,要修改該配置文件。 日志的作用: 用于記錄系統、程序運行中發生的各種事件; 通過閱讀日志,有助于診斷和解決系統故障 日志文件的分類: 內核及系統日志 由系統服務rsyslog統一進行管理,日志格式基本相似 用戶日志 記錄系統用戶登錄及退出系統的相關...

    圖像混合模式:Android Paint Xfermode 使用和demo

    一、setXfermode(Xfermode xfermode) Xfermode國外有大神稱之為過渡模式,這種翻譯比較貼切但恐怕不易理解,大家也可以直接稱之為圖像混合模式,因為所謂的“過渡”其實就是圖像混合的一種,這個方法跟我們上面講到的setColorFilter蠻相似的。查看API文檔發現其果然有三個子類:AvoidXfermode, PixelXorXfermode...

    混合使用XML布局文件和代碼控制視圖

    本實例包含二個布局文件 activity_main.xml和text.xml text.xml MainActivity.main` 運行結果 說明 :在本例中如果把` LinearLayout linearLayout1=(LinearLayout)getLayoutInflater().inflate(R.layout.test, null); linearLayout.addView(lin...

    Xfermode圖像混合模式

    1:Xfermode介紹 什么是Xfermode 這個不好解釋,api翻譯出來的也很拗口。習慣性叫圖片混合模式 api的描述大概是:Xfermode是在繪圖通道中自定義“傳輸模式”的基類。靜態函數創建可以調用或者返回任意作為模式枚舉指定的預定義子類實例。當Xfermode分配給Paint,然后繪制對象與Paint就具備了所添加的xfermode,就是給paint畫筆設置一個...

    hive 導出數據之一列多行,轉為一行多列

    需求:提取數據 說明:原數據是一列多行,需要轉化為一行多列 待查詢表為:temp_05 待查詢數據為: 待查詢數據如圖: 需要提取的數據表頭如下: 預定日期 昨日價格 前天價格 2018-02-01 2018-02-02 2018-02-03 2018-02-04 可用提數 SQL 數據如圖: 以下為嘗試過程 數據如圖: 數據如圖: 數據如圖: 數據如圖:...

    猜你喜歡

    asp.net做一個簡易的聊天室

    要求: 結果: 關鍵代碼: Default.aspx Default.aspx.cs Default2.aspx Default2.aspx.cs Default3.aspx Default3.aspx.cs Default4.aspx...

    動態SQL和多表關聯-筆記

    《動態SQL與多表關聯》筆記 學習目標 能夠使用動態SQL完成SQL拼接 能夠使用resultMap完成多表查詢 能夠使用一對一查詢 能夠使用一對多查詢 (注:多對多其實就是兩個一個多) 映射文件:為什么要resultMap 目標 定義結果映射 使用結果映射 回顧 在mybatis中有2種配置文件: 核心配置文件,如:sqlMapConfig.xml 實體類映射文件,如:UserMapper.xm...

    【OpenGL C++ UE4】獲取模型頂點及面索引數據,并優化存儲結構供UE4繪制

    目錄 一、功能需求 二、成果 三、環境配置 四、詳細步驟 4.1 Max制作三棱錐并處理 4.2 核心代碼 4.2.1 傳入結構體數據 4.2.2 頂點去重、更新索引 4.2.3 輸出本地CSV文件 4.3 UE4繪制 一、功能需求 想必你肯定會問我一個問題,UE4直接導入模型不好么? 哈哈,前提是在做畢設時,導師提供的只有頂點與面索引數據,沒有模型。 下文詳細介紹了畢設開發中的難點,涉...

    解決Pyinstaller打包numpy和pandas庫文件過大問題

    解決Pyinstaller壓縮numpy和pandas庫文件過大問題 文件包類型和網上的方法 Windows下docker的安裝 在docker下實現打包     今天是2021年的第一天,先祝各位小伙伴現年快樂哈。最近因為做了一個項目,需要打包文件,文件中包含了numpy和pandas庫,結果打包出來幾百行的代碼居然要900m,人都傻了,翻遍了全網找解決方...

    精品国产乱码久久久久久蜜桃不卡