Simple Log Service (SLS) のデータ変換関数を使用して、収集された大量のログデータをクレンジングし、データ形式を標準化します。このトピックでは、関数を呼び出してデータをクレンジングするための一般的なユースケースと関連する操作について説明します。
ユースケース 1: ログのフィルター (e_keep および e_drop 関数)
e_drop または e_keep 関数を使用してログをフィルターします。また、e_if または 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 関数を使用して、空のログフィールドに値を割り当てます。
元のフィールドが存在しないか空の場合に、フィールドに値を割り当てます。
e_set("result", "......value......", mode="fill")mode パラメーターの値の詳細については、「フィールド抽出チェックと上書きモード」をご参照ください。
例:
生のログ
name:変換ルール
e_set("name", "aspara2.0", mode="fill")変換結果
name: aspara2.0
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"
複数のフィールドに値を割り当てます。
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、ct_int、および dt_totimestamp 関数)
データ変換中、ログフィールドとその値は常に文字列です。文字列以外の型のデータは、自動的に文字列型に変換されます。したがって、関数を呼び出すときは、その関数が受け入れるパラメーターの型に注意してください。詳細については、「構文の概要」をご参照ください。
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
a:1 b:2 d:12 e:3
フィールド操作関数と 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
dt_parse 関数と dt_parsetimestamp 関数を呼び出して、文字列または datetime オブジェクトを標準の時間形式に変換します。
dt_totimestamp 関数は、文字列ではなく datetime オブジェクトを受け入れます。したがって、dt_parse 関数を呼び出して time1 の文字列値を datetime オブジェクトに変換する必要があります。datetime オブジェクトと文字列の両方を受け入れる dt_parsetimestamp 関数を直接使用することもできます。詳細については、「日付と時刻の関数」をご参照ください。
例:
生のログ
time1: 2020-09-17 9:00:00変換ルール
time1 で表される日時を UNIX タイムスタンプに変換します。
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: 存在しないログフィールドをデフォルト値で埋める (default パラメーターを渡す)
一部の SLS 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(condition1, operation1, condition2, operation2, condition3, operation3, ....)e_switch 関数
e_switch 関数は、条件と操作のペアの組み合わせです。この関数は条件を順次チェックします。条件が満たされると、対応する操作が実行され、結果がすぐに返されます。条件が満たされない場合、関数は次の条件をチェックします。どの条件も満たされず、default パラメーターが設定されている場合、default に設定された操作が実行され、その結果が返されます。
e_switch(condition1, operation1, condition2, operation2, condition3, operation3, ...., default=None)
例:
生のログ
status1: 200 status2: 404e_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"))変換結果
いずれかの条件が満たされると、結果が返され、それ以降の条件はチェックされません。
status1: 200 status2: 404 status1_info: normal
ユースケース 7: データをナノ秒レベルの UNIX タイムスタンプに変換する
一部のユースケースでは、SLS のデータ変換はナノ秒レベルのタイムスタンプ精度をサポートする必要があります。生ログに 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 タイムスタンプに変換する
一部のユースケースでは、SLS のデータ変換は高精度のタイムスタンプをサポートする必要があります。生ログに標準 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" }