DISSECT と GROK を使用したデータ処理

あなたのデータには、構造化したい非構造化文字列が含まれているかもしれません。これにより、データの分析が容易になります。たとえば、ログメッセージには、最もアクティブな IP アドレスを見つけるために抽出したい IP アドレスが含まれている場合があります。

非構造化データ

Elasticsearch は、インデックス時またはクエリ時にデータを構造化できます。インデックス時には、Dissect および Grok インジェストプロセッサ、または Logstash の Dissect および Grok フィルタを使用できます。クエリ時には、ES|QL DISSECT および GROK コマンドを使用できます。

DISSECT または GROK?それとも両方?

DISSECT は、区切り文字ベースのパターンを使用して文字列を分割します。GROK は同様に機能しますが、正規表現を使用します。これにより、GROK はより強力になりますが、一般的には遅くなります。DISSECT は、データが確実に繰り返される場合にうまく機能します。GROK は、テキストの構造が行ごとに異なる場合など、正規表現の力が本当に必要な場合により良い選択です。

DISSECTGROK の両方をハイブリッドユースケースに使用できます。たとえば、行の一部が確実に繰り返されるが、全体の行はそうでない場合です。DISSECT は繰り返される行の部分を分解できます。GROK は、正規表現を使用して残りのフィールド値を処理できます。

DISSECT を使用したデータ処理

DISSECT 処理コマンドは、区切り文字ベースのパターンに対して文字列を一致させ、指定されたキーを列として抽出します。

たとえば、次のパターン:

テキスト

  1. %{clientip} [%{@timestamp}] %{status}

この形式のログ行に一致します:

テキスト

  1. 1.2.3.4 [2023-01-23T12:15:00.000Z] Connected

その結果、入力テーブルに次の列が追加されます:

clientip:keyword @timestamp:keyword status:keyword
1.2.3.4 2023-01-23T12:15:00.000Z 接続済み

分解パターン

分解パターンは、破棄される文字列の部分によって定義されます。前の例では、最初に破棄される部分は単一のスペースです。Dissect はこのスペースを見つけ、その後 clientip の値をそのスペースまで割り当てます。次に、dissect は [ に一致し、その後 ] に一致し、@timestamp[] の間のすべてに割り当てます。破棄する文字列の部分に特に注意を払うことで、成功した分解パターンを構築するのに役立ちます。

空のキー (%{}) または 名前付きスキップキー を使用して値に一致させることができますが、出力からその値を除外します。

すべての一致した値は、キーワード文字列データ型として出力されます。型変換関数を使用して、別のデータ型に変換します。

Dissect は、dissect のデフォルトの動作を変更できる キー修飾子 もサポートしています。たとえば、特定のフィールドを無視したり、フィールドを追加したり、パディングをスキップしたりするように指示できます。

用語

  • 分解パターン
  • テキスト形式を説明するフィールドと区切り文字のセット。分解とも呼ばれます。分解は、%{} セクションのセットを使用して説明されます: %{a} - %{b} - %{c}
  • フィールド
  • %{ から } までのテキスト(両端を含む)。
  • 区切り文字
  • } と次の %{ 文字の間のテキスト。%{'not }'、または } 以外の任意の文字のセットが区切り文字です。
  • キー
  • %{} の間のテキスト(?+& プレフィックスと序数接尾辞を除く)。
    例:
    • %{?aaa} - キーは aaa です。
    • %{+bbb/3} - キーは bbb です。
    • %{&ccc} - キーは ccc です。

次の例は、タイムスタンプ、テキスト、および IP アドレスを含む文字列を解析します:

Esql

  1. ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
  2. | DISSECT a "%{date} - %{msg} - %{ip}"
  3. | KEEP date, msg, ip
date:keyword msg:keyword ip:keyword
2023-01-23T12:15:00.000Z 一部のテキスト 127.0.0.1

デフォルトでは、DISSECT はキーワード文字列列を出力します。別の型に変換するには、型変換関数を使用します:

Esql

  1. ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
  2. | DISSECT a "%{date} - %{msg} - %{ip}"
  3. | KEEP date, msg, ip
  4. | EVAL date = TO_DATETIME(date)
msg:keyword ip:keyword date:date
一部のテキスト 127.0.0.1 2023-01-23T12:15:00.000Z

Dissect キー修飾子

キー修飾子は、分解のデフォルトの動作を変更できます。キー修飾子は、常に %{keyname} の左または右にあり、%{} の内部にあります。たとえば、%{+keyname ->} には追加および右パディング修飾子があります。


表 80. 分解キー修飾子

修飾子 名前 位置 説明 詳細
-> 右パディングをスキップ (遠い) 右 %{keyname1->} 右側の繰り返された文字をスキップします リンク
+ 追加 %{+keyname} %{+keyname} 2 つ以上のフィールドを一緒に追加します リンク
+/n 順序付き追加 左と右 %{+keyname/2} %{+keyname/1} 指定された順序で 2 つ以上のフィールドを一緒に追加します リンク
? 名前付きスキップキー %{?ignoreme} 出力で一致した値をスキップします。%{} と同じ動作 リンク

右パディング修飾子 (-“)

分解を実行するアルゴリズムは、パターン内のすべての文字がソース文字列と一致する必要があるという点で非常に厳格です。たとえば、パターン %{fookey} %{barkey} (1 スペース) は、文字列 “foobar” (1 スペース) に一致しますが、パターンには 1 スペースしかなく、ソース文字列には 2 スペースがあるため、文字列 “foobar” (2 スペース) には一致しません。

右パディング修飾子は、この場合に役立ちます。パターン %{fookey->} %{barkey} に右パディング修飾子を追加すると、”foobar” (1 スペース) と “foobar” (2 スペース) および “foobar” (10 スペース) に一致します。

右パディング修飾子を使用して、%{keyname->} の後の文字の繰り返しを許可します。

右パディング修飾子は、他の修飾子とともに任意のキーに配置できます。常に最も右の修飾子である必要があります。たとえば: %{+keyname/1->}%{->}

たとえば:

Esql

  1. ROW message="1998-08-10T17:15:42 WARN"
  2. | DISSECT message "%{ts->} %{level}"
message:keyword ts:keyword level:keyword
1998-08-10T17:15:42 WARN 1998-08-10T17:15:42 WARN

右パディング修飾子は、不要なデータをスキップするのに役立つ空のキーとともに使用できます。たとえば、同じ入力文字列ですが、ブラケットで囲まれている場合、同じ結果を得るには空の右パディングキーを使用する必要があります。

たとえば:

Esql

  1. ROW message="[1998-08-10T17:15:42] [WARN]"
  2. | DISSECT message "[%{ts}]%{->}[%{level}]"
message:keyword ts:keyword level:keyword
[“[1998-08-10T17:15:42] [WARN]“] 1998-08-10T17:15:42 WARN

追加修飾子 (+)

Dissect は、出力のために 2 つ以上の結果を一緒に追加することをサポートしています。値は左から右に追加されます。追加セパレーターを指定できます。この例では、追加セパレーターはスペースとして定義されています。

Esql

  1. ROW message="john jacob jingleheimer schmidt"
  2. | DISSECT message "%{+name} %{+name} %{+name} %{+name}" APPEND_SEPARATOR=" "
message:keyword name:keyword
john jacob jingleheimer schmidt john jacob jingleheimer schmidt

順序付き追加修飾子 (+ と /n)

Dissect は、出力のために 2 つ以上の結果を一緒に追加することをサポートしています。値は定義された順序 (/n) に基づいて追加されます。追加セパレーターを指定できます。この例では、追加セパレーターはカンマとして定義されています。

Esql

  1. ROW message="john jacob jingleheimer schmidt"
  2. | DISSECT message "%{+name/2} %{+name/4} %{+name/3} %{+name/1}" APPEND_SEPARATOR=","
message:keyword name:keyword
john jacob jingleheimer schmidt schmidt,john,jingleheimer,jacob

名前付きスキップキー (?)

Dissect は、最終結果で一致を無視することをサポートしています。これは、空のキー %{} を使用して行うことができますが、可読性のために、その空のキーに名前を付けることが望ましい場合があります。

これは、{?name} 構文を使用して名前付きスキップキーを使用することで実現できます。次のクエリでは、identauth は出力テーブルに追加されません:

Esql

  1. ROW message="1.2.3.4 - - 30/Apr/1998:22:00:52 +0000"
  2. | DISSECT message "%{clientip} %{?ident} %{?auth} %{@timestamp}"
message:keyword clientip:keyword @timestamp:keyword
1.2.3.4 - - 30/Apr/1998:22:00:52 +0000 1.2.3.4 30/Apr/1998:22:00:52 +0000

制限事項

DISSECT コマンドは、参照キーをサポートしていません。

GROK を使用したデータ処理

GROK 処理コマンドは、正規表現に基づくパターンに対して文字列を一致させ、指定されたキーを列として抽出します。

たとえば、次のパターン:

テキスト

  1. %{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}

この形式のログ行に一致します:

テキスト

  1. 1.2.3.4 [2023-01-23T12:15:00.000Z] Connected

ES|QL クエリとしてまとめると:

Esql

  1. ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
  2. | GROK a "%{IP:ip} \\[%{TIMESTAMP_ISO8601:@timestamp}\\] %{GREEDYDATA:status}"

GROK は、入力テーブルに次の列を追加します:

@timestamp:keyword ip:keyword status:keyword
2023-01-23T12:15:00.000Z 1.2.3.4 接続済み

grok パターン内の特殊な正規表現文字、[] は、\ でエスケープする必要があります。たとえば、前のパターンでは:

テキスト

  1. %{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}

ES|QL クエリでは、バックスラッシュ文字自体が特殊文字であり、別の \ でエスケープする必要があります。この例では、対応する ES|QL クエリは次のようになります:

Esql

  1. ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
  2. | GROK a "%{IP:ip} \\[%{TIMESTAMP_ISO8601:@timestamp}\\] %{GREEDYDATA:status}"

Grok パターン

grok パターンの構文は %{SYNTAX:SEMANTIC} です。

SYNTAX は、あなたのテキストに一致するパターンの名前です。たとえば、3.44NUMBER パターンに一致し、55.3.244.1IP パターンに一致します。構文は、どのように一致させるかです。

SEMANTIC は、一致しているテキストの部分に与える識別子です。たとえば、3.44 はイベントの期間を示すことができるので、単に duration と呼ぶことができます。さらに、文字列 55.3.244.1 は、リクエストを行っている client を識別するかもしれません。

デフォルトでは、一致した値はキーワード文字列データ型として出力されます。意味のデータ型を変換するには、ターゲットデータ型でサフィックスを付けます。たとえば、%{NUMBER:num:int} は、num 意味を文字列から整数に変換します。現在サポートされている変換は intfloat のみです。他の型については、型変換関数を使用してください。

利用可能なパターンの概要については、GitHubを参照してください。また、REST APIを使用して、すべてのパターンのリストを取得することもできます。

正規表現

Grok は正規表現に基づいています。grok でも有効な正規表現はすべて有効です。Grok は Oniguruma 正規表現ライブラリを使用しています。完全なサポートされている regexp 構文については、Oniguruma GitHub リポジトリを参照してください。

カスタムパターン

grok に必要なパターンがない場合は、テキストの一部を一致させて列として保存できる名前付きキャプチャの Oniguruma 構文を使用できます:

テキスト

  1. (?<field_name>the pattern here)

たとえば、postfix ログには、10 または 11 文字の16進数値である queue id があります。これは、次のように queue_id という名前の列にキャプチャできます:

テキスト

  1. (?<queue_id>[0-9A-F]{10,11})

次の例は、タイムスタンプ、IP アドレス、メールアドレス、および数値を含む文字列を解析します:

Esql

  1. ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42"
  2. | GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}"
  3. | KEEP date, ip, email, num
date:keyword ip:keyword email:keyword num:keyword
2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42

デフォルトでは、GROK はキーワード文字列列を出力します。int および float 型は、パターン内の意味に :type を追加することで変換できます。たとえば {NUMBER:num:int}

Esql

  1. ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42"
  2. | GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"
  3. | KEEP date, ip, email, num
date:keyword ip:keyword email:keyword num:integer
2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42

他の型変換については、型変換関数を使用してください:

Esql

  1. ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42"
  2. | GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"
  3. | KEEP date, ip, email, num
  4. | EVAL date = TO_DATETIME(date)
ip:keyword email:keyword num:integer date:date
127.0.0.1 [email protected] 42 2023-01-23T12:15:00.000Z

フィールド名が複数回使用されると、GROK は多値列を作成します:

Esql

  1. FROM addresses
  2. | KEEP city.name, zip_code
  3. | GROK zip_code "%{WORD:zip_parts} %{WORD:zip_parts}"
city.name:keyword zip_code:keyword zip_parts:keyword
アムステルダム 1016 ED [“1016”, “ED”]
サンフランシスコ CA 94108 [“CA”, “94108”]
東京 100-7014 null

Grok デバッガー

grok パターンを作成およびデバッグするには、Grok デバッガーを使用できます。これは、サンプルデータに対してパターンをテストするための UI を提供します。内部では、GROK コマンドと同じエンジンを使用しています。

制限事項

GROK コマンドは、カスタムパターン複数のパターンの設定をサポートしていません。GROK コマンドは、Grok ウォッチドッグ設定の対象ではありません。