すべてのプロダクト
Search
ドキュメントセンター

Simple Log Service:関数を使用してデータを浄化する

最終更新日:Aug 28, 2024

Simple Log Serviceが提供するデータ変換機能を使用して、大量のログデータをクレンジングできます。 このようにして、ログデータのフォーマットが標準化される。 このトピックでは、関数を使用してさまざまなシナリオでデータをクレンジングする方法について説明します。

シナリオ1: e_keep関数とe_drop関数を使用してログをフィルタリングする

e_dropまたはe_keep関数を使用してログをフィルタリングできます。 e_if関数とDROPパラメーターを組み合わせたり、e_if_else関数とDROPパラメーターを組み合わせてログをフィルタリングすることもできます。

一般的な変換ルール:

  • e_keep(e_search(...) ): 指定された条件を満たすログは保持されますが、指定された条件を満たさないログは破棄されます。

  • e_drop(e_search(...) ): 指定された条件を満たすログは破棄されますが、指定された条件を満たさないログは保持されます。

  • e_if_else(e_search("..."), KEEP, DROP): 指定された条件を満たすログは保持されますが、指定された条件を満たさないログは破棄されます。

  • e_if(e_search("not ..."), DROP): 指定された条件を満たすログは破棄されますが、指定された条件を満たさないログは保持されます。

  • e_if(e_search("..."), KEEP): この変換ルールは無効です。

例:

  • 生ログ

    # Log 1
    __source__:  192.168.0.1
    __tag__:__client_ip__:  192.168.0.2
    __tag__:__receive_time__:  1597214851
    __topic__: app 
    class:  test_case
    id:  7992
    test_string:  <function test1 at 0x1027401e0>
    
    # Log 2
    __source__:  192.168.0.1
    class:  produce_case
    id:  7990
    test_string:  <function test1 at 0x1020401e0>
  • 変換ルール

    __topic__ および __tag __:__ receive_time__ フィールドを含まないログを破棄します。

    e_if(e_not_has("__topic__"),e_drop())
    e_if(e_not_has("__tag__:__receive_time__"),e_drop())
  • 結果

    __source__:  192.168.0.1
    __tag__:__client_ip__:  192.168.0.2
    __tag__:__receive_time__:  1597214851
    __topic__: app 
    class:  test_case
    id:  7992
    test_string:  <function test1 at 0x1027401e0>

シナリオ2: e_set関数を使用してログ内の空のフィールドに値を割り当てる

e_set関数を使用して、ログの空のフィールドに値を割り当てることができます。

  • サブシナリオ1: フィールドが存在しないか空の場合、フィールドに値を割り当てます。

    e_set("result", "......value......", mode="fill")

    modeパラメーター値の詳細については、「フィールド抽出チェックモードと上書きモード」をご参照ください。

    例:

    • 生ログ

      name:
    • 変換ルール

      e_set("name", "aspara2.0", mode="fill")
    • 結果

      name:  aspara2.0
  • サブシナリオ2: 正規表現を単純化し、Grok関数を使用してフィールド値を抽出します。

    例:

    • 生ログ

      content:"ip address: 192.168.1.1"
    • 変換ルール

      Grok関数を使用して、contentフィールドのIPアドレスをキャプチャして抽出します。

      e_regex("content", grok(r"(%{IP})"),"addr")
    • 結果

      addr:  192.168.1.1
      content:"ip address: 192.168.1.1"
  • サブシナリオ3: 複数のフィールドに値を割り当てます。

    e_set("k1", "v1", "k2", "v2", "k3", "v3", ......)

    例:

    • 生ログ

      __source__:  192.168.0.1
      __topic__:
      __tag__:
      __receive_time__:
      id:  7990
      test_string:  <function test1 at 0x1020401e0>
    • 変換ルール

      __topic____tag__ 、および __receive_time__ フィールドに値を割り当てます。

      e_set("__topic__","app", "__tag__","stu","__receive_time__","1597214851")
    • 結果

      __source__:  192.168.0.1
      __topic__:  app
      __tag__:  stu
      __receive_time__:  1597214851
      id:  7990
      test_string:  <function test1 at 0x1020401e0>

シナリオ3: e_search、e_rename、およびe_compose関数を使用してフィールドを削除し、フィールドの名前を変更する

ほとんどの場合、e_compose関数を使用して、指定された条件に基づいてデータを評価し、評価結果に基づいて操作を実行することをお勧めします。

例:

  • 生ログ

    content:123
    age: 23
    name:twiss
  • 変換ルール

    contentフィールドの値が123の場合は、ageフィールドとnameフィールドを削除します。 次に、contentフィールドの名前をctxに変更します。

    e_if(e_search("content==123"),e_compose(e_drop_fields("age|name"), e_rename("content", "ctx")))
  • 結果

    ctx: 123

シナリオ4: v、cn_int、dt_totimestamp関数を使用して、ログ内のフィールドのデータ型を変換します。

ログのフィールドとフィールド値は、データ変換中に文字列として処理されます。 非文字列型のデータは、文字列型のデータへ自動的に変換されます。 関数を呼び出すときは、関数でサポートされているデータ型に注意してください。 詳細については、「構文の概要」をご参照ください。

  • サブシナリオ1: op_add関数を使用して文字列を連結し、データを合計します。

    op_add関数は、文字列型と数値型をサポートします。 したがって、データ型の変換は必要ありません。

    例:

    • 生ログ

      a : 1
      b : 2
    • 変換ルール

      e_set("d",op_add(v("a"), v("b")))
      e_set("e",op_add(ct_int(v("a")), ct_int(v("b"))))
    • 結果

      a:1
      b:2
      d:12
      e:3
  • サブシナリオ2: Field processing関数とct_int関数を使用してデータ型を変換し、op_mul関数を呼び出してデータを乗算します。

    例:

    • 生ログ

      a:2
      b:5
    • 変換ルール

      v("a") とv("b") は文字列型です。 op_mul関数の2番目のパラメーターは、数値型のみにすることができます。 この場合、ct_int関数を使用して文字列を整数に変換し、その整数をop_mul関数に渡す必要があります。

      e_set("c",op_mul(ct_int(v("a")), ct_int(v("b"))))
      e_set("d",op_mul(v("a"), ct_int(v("b"))))
    • 結果

      a: 2
      b: 5
      c: 10
      d: 22222
  • サブシナリオ3: dt_parseおよびdt_parsetimestamp関数を使用して、文字列またはdatetimeを標準時刻に変換します。

    dt_totimestamp関数は、datetimeオブジェクトタイプをサポートします。 dt_totimestamp関数はstring型をサポートしていません。 この場合、dt_parse関数を呼び出して、string型のtime1をdatetimeオブジェクト型に変換する必要があります。 dt_parsetimestamp関数を使用することもできます。 dt_parsetimestamp関数は、datetimeオブジェクト型と文字列型をサポートします。 詳細については、「日付と時刻の関数」をご参照ください。

    例:

    • 生ログ

      time1: 2020-09-17 9:00:00
    • 変換ルール

      time1で指定されたdatetimeをUNIX timestampに変換します。

      e_set("time1", "2019-06-03 2:41:26")
      e_set("time2", dt_totimestamp(dt_parse(v("time1")))) or e_set("time2", dt_parsetimestamp(v("time1")))
    • 結果

      time1:  2019-06-03 2:41:26 
      time2:  1559529686 

シナリオ5: デフォルトパラメータを設定して、ログに存在しないフィールドにデフォルト値を渡す

Simple Log Serviceのドメイン固有言語 (DSL) で提供される一部の式関数には、入力パラメーターに固有の要件があります。 入力パラメーターが要件を満たさない場合、関数を使用するデータ変換ルールはデフォルト値またはエラーを返します。 ログフィールドが必要だが空のままである場合は、op_len関数を使用してフィールドにデフォルト値を渡すことができます。

重要

デフォルト値が後続の関数に渡されると、エラーが発生する可能性があります。 できるだけ早い機会にエラーを処理することを推奨します。

  • 生ログ

    data_len: 1024
  • 変換ルール

    e_set("data_len", op_len(v("data", default="")))
  • 結果

    data: 0
    data_len: 0

シナリオ6: e_ifおよびe_switch関数を使用して、指定された条件に基づいてログを評価し、評価結果に基づいてフィールドを追加します。

e_ifまたはe_switch関数を使用してログを評価することを推奨します。 詳細については、「フロー制御機能」をご参照ください。

  • e_if関数

    e_if(Condition 1, Operation 1, Condition 2, Operation 2, Condition 3, Operation 3, ....)
  • e_switch関数

    e_switch関数を使用する場合は、条件と操作のペアを指定する必要があります。 e_switch関数は条件を順番に評価します。 条件が満たされると、そのペアリングされた操作が実行され、操作結果が返されます。 条件が満たされない場合、そのペアリング操作は実行されず、次の条件が評価されます。 条件が満たされず、defaultフィールドが指定されている場合、defaultで指定された操作が実行され、操作結果が返されます。

    e_switch(Condition 1, Operation 1, Condition 2, Operation 2, Condition 3, Operation 3, ...., default=None)

例:

  • 生ログ

    status1: 200
    status2: 404
  • e_if関数

    • 変換ルール

      e_if(e_match("status1", "200"), e_set("status1_info", "normal"),
           e_match("status2", "404"), e_set("status2_info", "error"))
    • 結果

      status1: 200
      status2: 404
      status1_info: normal
      status2_info: error
  • e_switch関数

    • 変換ルール

      e_switch(e_match("status1", "200"), e_set("status1_info", "normal"), 
               e_match("status2", "404"), e_set("status2_info", "error"))
    • 結果

      e_switch関数は条件を順番に評価します。 条件が満たされると、操作結果が返され、それ以上の条件は評価されません。

      status1: 200
      status2: 404
      status1_info: normal

シナリオ7: UNIXタイムスタンプをナノ秒の正確なログ時間値に変換する

一部のデータ変換シナリオでは、データのタイムスタンプはナノ秒まで正確でなければなりません。 生のログにUNIXタイムスタンプの値を持つフィールドが含まれている場合、フィールド処理関数を使用して、フィールド値をナノ秒の正確なログ時間に変換できます。

  • 生ログ

    {
      "__source__": "1.2.3.4",
      "__time__": 1704983810,
      "__topic__": "test",
      "log_time_nano":"1705043680630940602"
    }
  • 変換ルール

    e_set(
        "__time__", op_div_floor(ct_int(v("log_time_nano")), 1000000000),
    )
    e_set(
        "__time_ns_part__", op_mod(ct_int(v("log_time_nano")), 1000000000),
    )
  • 結果

    {
      "__source__": "1.2.3.4",
      "__time__": 1705043680,
      "__time_ns_part__": 630940602,
      "__topic__": "test",
      "log_time_nano":"1705043680630940602"
    }

シナリオ8: ISO 8601標準に準拠したUNIXタイムスタンプを、マイクロ秒の正確なログ時間値に変換する

一部のデータ変換シナリオでは、高精度のタイムスタンプが必要です。 生のログにISO 8601規格に従った値のフィールドが含まれている場合、フィールド処理関数を使用して、フィールド値をマイクロ秒の正確なログ時間に変換できます。

  • 生ログ

    {
      "__source__": "1.2.3.4",
      "__time__": 1704983810,
      "__topic__": "test",
      "log_time":"2024-01-11 23:10:43.992847200"
    }
  • 変換ルール

    e_set(
        "__time__", dt_parsetimestamp(v("log_time"), tz="Asia/Shanghai"), mode="overwrite",
    )
    e_set("tmp_ms", dt_prop(v("log_time"), "microsecond"))
    e_set(
        "__time_ns_part__", op_mul(ct_int(v("tmp_ms")), 1000),
    )
  • 結果

    {
      "__source__": "1.2.3.4",
      "__time__": 1704985843,
      "__time_ns_part__": 992847000,
      "__topic__": "test",
      "log_time": "2024-01-11 23:10:43.992847200",
      "tmp_ms": "992847"
    }