全部產品
Search
文件中心

Simple Log Service:提取字串動態索引值對

更新時間:Jul 30, 2024

本文檔介紹如何使用不同方案提取字串索引值對。

常用方案比較

字串動態索引值對提取分為關鍵字提取、值提取、關鍵字加工和值加工,常用方案為採用e_kv函數、e_kv_delimit函數和e_regex函數等。不同提取情境的三種方案如下:

方案

關鍵字提取

值提取

關鍵字加工

值加工

e_kv

使用特定Regex

支援預設的字元集、特定分隔字元或者帶(、)或(")分隔

支援前尾碼

支援文本escape

e_kv_delimit

使用特定Regex

使用分隔字元

支援前尾碼

預設無

e_regex

組合自訂Regex和預設字元集過濾

完全自訂

自訂

自訂

大部分索引值對的提取使用e_kv函數並配置特定參數就可以很好地滿足,尤其是帶括字元和反斜線需要提取並轉義時。其他複雜或進階的情境可以用e_regex函數來提取。部分特定情境下的索引值對使用e_kv_delimit函數會更簡單。

關鍵字提取

  • 處理方法

    e_kve_kv_delimite_regex等函數在應用於關鍵字提取的時候都應遵循欄位名提取約束

  • 樣本1

    k1: q=asd&a=1&b=2&__1__=3日誌為例,如果要對該格式的日誌作關鍵字和值提取,三種方案如下:

    • e_kv函數

      • 原始日誌

        k1: q=asd&a=1&b=2&__1__=3
      • 加工規則

        #預設以特定字元集提取關鍵字
        e_kv("k1")
      • 加工結果

        k1: q=asd&a=1&b=2
        q: asd
        a: 1
        b: 2
        說明

        沒有提取出關鍵字__1__是因為其不符合欄位名提取約束

    • e_kv_delimit函數

      • 原始日誌

        k1: q=asd&a=1&b=2&__1__=3
      • 加工規則

        # 以&分隔索引值後,用&分隔提取出關鍵字
        e_kv_delimit("k1", pair_sep=r"&")
      • 加工結果

        k1: q=asd&a=1&b=2
        q: asd
        a: 1
        b: 2
    • e_regex函數

      • 原始日誌

        k1: q=asd&a=1&b=2&__1__=3
      • 加工規則

        # 自行指定字元集提取關鍵字和值
        e_regex("k1",r"(\w+)=([a-zA-Z0-9]+)",{r"\1": r"\2"})
      • 加工結果

        k1: q=asd&a=1&b=2
        q: asd
        a: 1
        b: 2
  • 樣本2

    content:k1=v1&k2=v2?k3:v3為例,需要特定正則提取關鍵字,三種方案如下:

    • e_kv函數

      • 原始日誌

        content:k1=v1&k2=v2?k3:v3
      • 加工規則

        e_kv("content",sep="(?:=|:)")
      • 加工結果

        content:k1=v1&k2=v2?k3:v3
        k1: v1
        k2: v2
        k3: v3
        說明

        給參數pair_sepkv_sep或者sep傳遞字元集的時候,需要使用正則的不捕獲分組,形式如(?:字元集)

    • e_kv_delimit函數

      • 原始日誌

        content:k1=v1&k2=v2?k3:v3
      • 加工規則

        e_kv_delimit("content",pair_sep=r"&?",kv_sep="(?:=|:)")
      • 加工結果

        content:k1=v1&k2=v2?k3:v3
        k1: v1
        k2: v2
        k3: v3
    • e_regex函數

      • 原始日誌

        content:k1=v1&k2=v2?k3:v3
      • 加工規則

        e_regex("content",r"([a-zA-Z0-9]+)[=|:]([a-zA-Z0-9]+)",{r"\1": r"\2"})
      • 加工結果

        content:k1=v1&k2=v2?k3:v3
        k1: v1
        k2: v2
        k3: v3
  • 樣本3

    對以下格式的複雜字串,使用e_regex函數提取更方便。

    • 原始日誌

      content :"ak_id:"LTAiscW,"ak_key:"rsd7r8f
    • 加工規則

      如果要提取字串的關鍵字前有(”)符號,需要使用e_regex函數來提取。

      e_regex("content", r"(\w+):\"(\w+)", {r"\1": r"\2"})
    • 加工結果

      經過DSL編排之後的日誌格式:

      content :"ak_id:"LTAiscW,"ak_key:"rsd7r8f
      ak_id: LTAiscW
      ak_key: rsd7r8f

值提取

  • 動態索引值對之間以及關鍵字與值之間有明確標識,如a=ba="cxxx"日誌格式的,推薦用e_kv函數,樣本如下。

    • 原始日誌

      content1:  k="helloworld",the change world, k2="good"
    • 加工規則

      這種情況下使用e_kv函數,提取內容不包括the change world

      e_kv("content1")
      # e_kv_delimit函數寫法,特別注意k2前有空格,所以e_kv_delimit函數的pair_sep參數需要使用`,\s`才能正常解析,否則解析不出來k2。
      e_kv_delimit("content1",kv_sep="=", pair_sep=",\s")
      # e_regex函數寫法
      e_regex("str",r"(\w+)=(\"\w+)",{r"\1": r"\2"})
    • 加工結果

      提取後的日誌為:

      content1:  k="helloworld",the change world, k2="good"
      k1: helloworld
      k2: good
  • 對帶"的日誌格式content:k1="v1=1"&k2=v2?k3=v3,推薦使用e_kv函數進行提取,例如:

    • 原始日誌

      content:k1="v1=1"&k2=v2?k3=v3
    • 加工規則

      e_kv("content",sep="=", quote="'")
    • 加工結果

      處理後日誌為:

      content: k1='v1=1'&k2=v2?k3=v3
      k1: v1=1
      k2:v2
      k3:v3

    如果使用e_kv_delimit函數提取,規則為e_kv_delimit("ctx", pair_sep=r"&?", kv_sep="="),只能解析出k2: v2k3: v3,因為其中第一個提取的索引值對中關鍵字是k1="v1,不符合欄位名提取約束會被丟棄。

  • 分隔字元的索引值對中,值包含特殊字元但沒有用特定字元包括。例如:

    • 原始日誌

      content:  rats eat rice, oil|chicks eat bugs, rice|kittens eat fish, mice|
    • 加工規則(推薦)

      使用e_kv_delimit函數比較合適。

      e_kv_delimit("content", pair_sep="|", kv_sep=" eat ")
    • 加工結果(推薦)

      處理後日誌為:

      content:  rats eat rice, oil|chicks eat bugs, rice|kittens eat fish, mice|
      kittens:  fish, mice
      chicks:  bugs, rice
      rats:  rice, oil
    • 加工規則(不推薦)

      使用e_kv函數無法解析完整。

      e_kv("f1", sep="eat")
    • 加工結果(不推薦)

      處理後日誌為:

      content:  rats eat rice, oil|chicks eat bugs, rice|kittens eat fish, mice|
      kittens:  fish
      chicks:  bugs
      rats:  rice

關鍵字加工

  • e_kv函數和e_kv_delimit函數都可以通過prefix="", suffix=""對關鍵字和值進行加工。

    • 原始日誌

      k1: q=asd&a=1&b=2
    • 加工規則

      e_kv("k1", sep="=", quote='"', prefix="start_", suffix="_end")
      e_kv_delimit("k1", pair_sep=r"&", kv_sep="=", prefix="start_", suffix="_end")
      e_regex("k1",r"(\w+)=([a-zA-Z0-9]+)",{r"start_\1_end": r"\2"})
    • 加工結果

      加工後的資料都是關鍵字加工形式,如下:

      k1: q=asd&a=1&b=2
      start_q_end: asd
      start_a_end: 1
      start_b_end: 2
  • e_regex函數對關鍵字加工的能力更強,例如:

    • 加工規則

      e_regex("k1",r"(\w+)=([a-zA-Z0-9]+)",{r"\1_\1": r"\2"})
    • 加工結果

      加工後的資料都是關鍵字加工形式,如下:

      k1: q=asd&a=1&b=2
      q_q: asd
      a_a: 1
      a_a: 2

值加工

  • 日誌格式為k1:"v1\"abc"形式, 同時值加工的內容存在有雙引號符號的情形,使用e_kv函數可正常進行提取,其他兩種方式較難實現。

    • 原始日誌

      """
      這裡的\只是普通的符號,不是轉義符
      """
      content2:  k1:"v1\"abc", k2:"v2", k3: "v3"
    • 加工規則1

      e_kv("content2",sep=":", quote='"')

      使用e_kv函數規則為:

    • 加工結果1

      提取後的日誌為:

      content2:  k1:"v1\"abc", k2:"v2", k3: "v3"
      k1: v1\
      k2: v2
      k3: v3
    • 加工規則2

      e_kv函數通過參數escape支援對\字元轉義。例如:

      e_kv("content2",sep=":", quote='"',escape=True)
    • 加工結果2

      提取後的日誌為:

      content2:  k1:"v1\"abc", k2:"v2", k3: "v3"
      k1: v1"abc
      k2: v2
      k3: v3
  • 日誌格式為a='k1=k2\';k2=k3'形式的日誌,只有e_kv函數可以正常提取出,其他兩種比較難以實現。

    • 原始日誌

      data: i=c10 a='k1=k2\';k2=k3'
    • 加工規則1

      預設情況下e_kv函數的escape=False,結果為:

      e_kv("data", quote="'")
    • 加工結果1

      提取後的日誌為:

      a:  k1=k2\
      i:  c10
      k2:  k3
    • 加工規則2

      e_kv函數通過參數escape支援對\字元轉義。例如:

      e_kv("data", quote="'", escape=True)
    • 加工結果2

      提取後的日誌為:

      data: i=c10 a='k1=k2\';k2=k3'
      i: c10
      a: k1=k2';k2=k3
  • 索引值的複雜加工。

    • 原始日誌

      content:  rats eat rice|chicks eat bugs|kittens eat fish|
    • 加工規則

      使用e_regex函數進行加工。

      e_regex("content", r"\b(\w+) eat ([^\|]+)", {r"\1": r"\2 by \1"})
    • 加工結果

      處理後日誌為:

      content:  rats eat rice|chicks eat bugs|kittens eat fish|
      kittens:  fish by kittens
      chicks:  bugs by chicks
      rats:  rice by rats

客戶案例

例如某網站日誌中有一個URL資料,針對這條資料有提取需求,按照需求設計加工規則處理日誌內容。

  • 第一次加工

    • 需求

      • 需求1:對日誌解析出protodomainparam等內容。

      • 需求2:對param中的索引值對做展開操作。

    • 原始日誌

      __source__:  192.168.0.100
      __tag__:__client_ip__:  192.168.0.200
      __tag__:__receive_time__:  1563517113
      __topic__:  
      request:  https://example.com/video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0
    • 加工方案

      • 總規則

        # 初步處理解析request內容
        e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?"))
        # 其次處理解析uri_param
        e_regex('uri_param',grok("%{GREEDYDATA:uri_path}\?%{GREEDYDATA:uri_query}"))
        # 展開kv形式
        e_kv("uri_query")
      • 細分規則及對應的加工結果

        1. 使用GROK模式對欄位request進行解析。

          也可以使用正則解析,請參見GROK函數GROK模式參考

          e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?"))

          對應加工結果:

          uri_domain:  example.com
          uri_param:  /video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0
          uri_proto:  https
        2. 使用GROK模式對欄位uri_param進行解析。

          e_regex('uri_param',grok("%{GREEDYDATA:uri_path}\?%{GREEDYDATA:uri_query}"))

          對應加工結果:

          uri_path:  /video/getlist/s
          uri_query:  ver=3.2.3&app_type=supplier&os=Android8.1.0
        3. uri_param進列欄位提取,具體操作如下:

          e_kv("uri_query")

          對應加工結果:

          app_type:  supplier
          os:  Android8.1.0
          ver:  3.2.3
  • 加工結果

    預覽處理後日誌:

    __source__:  192.168.0.100
    __tag__:__client_ip__:  192.168.0.200
    __tag__:__receive_time__:  1563517113
    __topic__:  
    request:  https://example.com/video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0
    uri_domain:  example.com
    uri_path:  /video/getlist/s
    uri_proto:  https
    uri_query:  ver=3.2.3&app_type=supplier&os=Android8.1.0
    app_type:  supplier
    os:  Android8.1.0
    ver:  3.2.3

    假如只有解析request需求,可以直接對欄位request使用e_kv函數。例如:

    e_kv("request")

    預覽處理後日誌:

    __source__:  192.168.0.100
    __tag__:__client_ip__:  192.168.0.200
    __tag__:__receive_time__:  1563517113
    __topic__:  
    request:  https://example.com/video/getlist/s?ver=3.2.3&app_type=supplier&os=Android8.1.0
    app_type:  supplier
    os:  Android8.1.0
    ver:  3.2.3
  • 進一步加工

    客戶要提取其中動態欄位verapp_typeos等,加工規則如下。

    • 使用Regex

      e_regex("url", r"\b(\w+)=([^=&]+)", {r"\1": r"\2"})
    • 使用e_kv_delmit函數

      e_kv_delimit("url", pair_sep=r"?&")
  • 方案總結

    對於大部分URL函數形式,都可使用以上函數進行解析。但是針對原始日誌中的URL形式,使用e_kv函數已經足夠,清晰明了而且形式簡單。