DISSECT と GROK を使用したデータ処理
あなたのデータには、構造化したい非構造化文字列が含まれているかもしれません。これにより、データの分析が容易になります。たとえば、ログメッセージには、最もアクティブな IP アドレスを見つけるために抽出したい IP アドレスが含まれている場合があります。
Elasticsearch は、インデックス時またはクエリ時にデータを構造化できます。インデックス時には、Dissect および Grok インジェストプロセッサ、または Logstash の Dissect および Grok フィルタを使用できます。クエリ時には、ES|QL DISSECT
および GROK
コマンドを使用できます。
DISSECT または GROK?それとも両方?
DISSECT
は、区切り文字ベースのパターンを使用して文字列を分割します。GROK
は同様に機能しますが、正規表現を使用します。これにより、GROK
はより強力になりますが、一般的には遅くなります。DISSECT
は、データが確実に繰り返される場合にうまく機能します。GROK
は、テキストの構造が行ごとに異なる場合など、正規表現の力が本当に必要な場合により良い選択です。
DISSECT
と GROK
の両方をハイブリッドユースケースに使用できます。たとえば、行の一部が確実に繰り返されるが、全体の行はそうでない場合です。DISSECT
は繰り返される行の部分を分解できます。GROK
は、正規表現を使用して残りのフィールド値を処理できます。
DISSECT を使用したデータ処理
DISSECT
処理コマンドは、区切り文字ベースのパターンに対して文字列を一致させ、指定されたキーを列として抽出します。
たとえば、次のパターン:
テキスト
%{clientip} [%{@timestamp}] %{status}
この形式のログ行に一致します:
テキスト
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
ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
| DISSECT a "%{date} - %{msg} - %{ip}"
| KEEP date, msg, ip
date:keyword | msg:keyword | ip:keyword |
---|---|---|
2023-01-23T12:15:00.000Z | 一部のテキスト | 127.0.0.1 |
デフォルトでは、DISSECT
はキーワード文字列列を出力します。別の型に変換するには、型変換関数を使用します:
Esql
ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
| DISSECT a "%{date} - %{msg} - %{ip}"
| KEEP date, msg, ip
| EVAL date = TO_DATETIME(date)
msg:keyword | ip:keyword | date:date |
---|---|---|
一部のテキスト | 127.0.0.1 | 2023-01-23T12:15:00.000Z |
Dissect キー修飾子
キー修飾子は、分解のデフォルトの動作を変更できます。キー修飾子は、常に %{keyname}
の左または右にあり、%{
と }
の内部にあります。たとえば、%{+keyname ->}
には追加および右パディング修飾子があります。
修飾子 | 名前 | 位置 | 例 | 説明 | 詳細 |
---|---|---|---|---|---|
-> |
右パディングをスキップ | (遠い) 右 | %{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
ROW message="1998-08-10T17:15:42 WARN"
| DISSECT message "%{ts->} %{level}"
message:keyword | ts:keyword | level:keyword |
---|---|---|
1998-08-10T17:15:42 WARN | 1998-08-10T17:15:42 | WARN |
右パディング修飾子は、不要なデータをスキップするのに役立つ空のキーとともに使用できます。たとえば、同じ入力文字列ですが、ブラケットで囲まれている場合、同じ結果を得るには空の右パディングキーを使用する必要があります。
たとえば:
Esql
ROW message="[1998-08-10T17:15:42] [WARN]"
| 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
ROW message="john jacob jingleheimer schmidt"
| 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
ROW message="john jacob jingleheimer schmidt"
| 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}
構文を使用して名前付きスキップキーを使用することで実現できます。次のクエリでは、ident
と auth
は出力テーブルに追加されません:
Esql
ROW message="1.2.3.4 - - 30/Apr/1998:22:00:52 +0000"
| 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
処理コマンドは、正規表現に基づくパターンに対して文字列を一致させ、指定されたキーを列として抽出します。
たとえば、次のパターン:
テキスト
%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}
この形式のログ行に一致します:
テキスト
1.2.3.4 [2023-01-23T12:15:00.000Z] Connected
ES|QL クエリとしてまとめると:
Esql
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
| 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 パターン内の特殊な正規表現文字、[
や ]
は、\
でエスケープする必要があります。たとえば、前のパターンでは:
テキスト
%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}
ES|QL クエリでは、バックスラッシュ文字自体が特殊文字であり、別の \
でエスケープする必要があります。この例では、対応する ES|QL クエリは次のようになります:
Esql
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
| GROK a "%{IP:ip} \\[%{TIMESTAMP_ISO8601:@timestamp}\\] %{GREEDYDATA:status}"
Grok パターン
grok パターンの構文は %{SYNTAX:SEMANTIC}
です。
SYNTAX
は、あなたのテキストに一致するパターンの名前です。たとえば、3.44
は NUMBER
パターンに一致し、55.3.244.1
は IP
パターンに一致します。構文は、どのように一致させるかです。
SEMANTIC
は、一致しているテキストの部分に与える識別子です。たとえば、3.44
はイベントの期間を示すことができるので、単に duration
と呼ぶことができます。さらに、文字列 55.3.244.1
は、リクエストを行っている client
を識別するかもしれません。
デフォルトでは、一致した値はキーワード文字列データ型として出力されます。意味のデータ型を変換するには、ターゲットデータ型でサフィックスを付けます。たとえば、%{NUMBER:num:int}
は、num
意味を文字列から整数に変換します。現在サポートされている変換は int
と float
のみです。他の型については、型変換関数を使用してください。
利用可能なパターンの概要については、GitHubを参照してください。また、REST APIを使用して、すべてのパターンのリストを取得することもできます。
正規表現
Grok は正規表現に基づいています。grok でも有効な正規表現はすべて有効です。Grok は Oniguruma 正規表現ライブラリを使用しています。完全なサポートされている regexp 構文については、Oniguruma GitHub リポジトリを参照してください。
カスタムパターン
grok に必要なパターンがない場合は、テキストの一部を一致させて列として保存できる名前付きキャプチャの Oniguruma 構文を使用できます:
テキスト
(?<field_name>the pattern here)
たとえば、postfix ログには、10 または 11 文字の16進数値である queue id
があります。これは、次のように queue_id
という名前の列にキャプチャできます:
テキスト
(?<queue_id>[0-9A-F]{10,11})
例
次の例は、タイムスタンプ、IP アドレス、メールアドレス、および数値を含む文字列を解析します:
Esql
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42"
| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}"
| 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
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42"
| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"
| 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
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 [email protected] 42"
| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"
| KEEP date, ip, email, num
| 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
FROM addresses
| KEEP city.name, zip_code
| 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 ウォッチドッグ設定の対象ではありません。