全文インデックス¶
全文インデックスとは¶
全文インデックスは、ログの全文検索方式のひとつです。有効にすると、システムはログ内のすべての業務フィールドを全文インデックスの対象とします。検索時には、事前にフィールド名を指定する必要はなく、任意の業務フィールドの値を入力するだけで、その値を含むログを検索できます。
たとえば、次のフィールドを含むログがあるとします。
全文インデックスを有効にすると、8d4f2a、O-1001、128.5 を直接検索して、このログを取得できます。
全文インデックスは、次のようなユースケースに適しています。
- ログがすでに複数の構造化フィールドとして抽出されており、もはや
messageの一塊に依存する必要がない。 trace_id、注文番号、ユーザー ID など、さまざまな業務フィールドからすばやく検索する必要がある。- 同じログインデックスに複数のログ構造が混在しており、すべてのログに対してあらかじめ統一された検索フィールドを決定できない。
- フィールドベースのクエリ機能を維持しつつ、業務フィールドを横断した全文検索もサポートしたい。
インデックスが message のみの場合との違い¶
| 比較項目 | message のみのインデックス |
全文インデックス |
|---|---|---|
| 全文検索の範囲 | message フィールドのみ |
すべての業務フィールド(message が存在する場合はそれを含む) |
| 元のログを保持する必要があるか | message を保持する必要あり |
必須ではない。保持してもよいし、フィールド抽出後に削除してもよい |
| 適したデータ | プレーンテキストログ、非構造化ログ | JSON ログ、Pipeline で抽出された構造化ログ |
| 全文インデックスが作成されるフィールド | message |
variant |
全文インデックスは全文検索の範囲を変更するだけで、フィールドフィルタリングを代替するものではありません。抽出済みのフィールドについては、引き続き service:order-api のようなフィールド条件を使用して、正確な絞り込み、集計、分析を行うことができます。
動作の仕組み¶
システムは variant を使用して全文インデックス内の業務フィールドを統一的に保持し、variant に対してのみ全文インデックスを作成します。
message が存在しない場合:
業務フィールド → variant → 全文インデックス
message が存在する場合:
message + その他の業務フィールド → variant → 全文インデックス
具体的なルールは次のとおりです。
- 全文インデックスにはログの業務フィールドが含まれ、システムフィールドは含まれません。
- ログに
messageが存在しない場合でも、他の業務フィールドは全文検索の対象となります。 - ログに
messageが存在する場合、システムはそのフィールドを削除せず、通常の業務フィールドとしてvariantに書き込みます。 - システムが
messageとvariantの両方に対して個別に全文インデックスを作成することはありません。 - 同じログインデックスに、
messageがあるログとないログを同時に保存できます。
message が存在するかどうかは、ログの元の内容と、DataKit および Pipeline による実際の処理結果によって決まります。全文インデックスを有効にしても、message を削除する必要はありません。
全文インデックスを有効にする¶
- ログ > インデックス に移動します。
- 新しいログインデックスを作成するか、対象のログインデックスを編集します。
- 詳細オプション を展開します。
- 全文インデックスフィールド で 全文インデックス を選択します。
- 設定を保存します。
前提条件
現在のワークスペースが全文インデックスをサポートしている必要があります。このオプションがページに表示されない場合は、ワークスペースのバージョンと関連機能の権限を確認してください。
全文インデックスを使用したクエリ¶
設定を完了し、ログを書き込んだ後、ログ > エクスプローラー に移動し、対応するログインデックスを選択します。
エクスプローラーでは、テキスト検索、フィールドフィルタリング、複合検索、JSON 検索、DQL クエリなどの方法がサポートされています。完全な検索構文と使用説明については、エクスプローラー検索 を参照してください。
全文検索¶
検索ボックスに業務フィールドの値を入力すると、フィールド名を指定することなく、すべての業務フィールドを検索できます。
上記の注文ログを例にとると、次のようになります。
O-1001と入力すると、order_idが一致します。8d4f2aと入力すると、trace_idが一致します。order-apiと入力すると、serviceが一致します。- ログに
messageが保持されている場合は、message内の内容も検索できます。
テキスト検索では、入力内容が分割(トークン化)されます。完全で連続した内容を一致させたい場合は、検索内容を半角の二重引用符で囲みます。詳細については、テキスト検索 を参照してください。
フィールドフィルタリング¶
フィールド名がすでにわかっている場合は、フィールド条件を使用してクエリ範囲を絞り込むことができます。例:
全文検索は「内容がどのフィールドにあるかわからない」場合に適しており、フィールドフィルタリングはフィールド名がわかっていて、正確な絞り込みや集計分析が必要な場合に適しています。両方を組み合わせて使用することもできます。フィールドフィルタリングの完全な構文については、フィルタリング を参照してください。
クエリに関する注意事項¶
- 全文検索では業務フィールドのみが一致の対象となり、システムフィールドは一致しません。
- ログに
messageがない場合、エクスプローラーは現在のログの業務フィールドを組み合わせてログ内容を表示します。 - システムフィールドは、全文インデックスのログ内容の一部にはなりません。
- 業務フィールドがまだ元のログから抽出されていない場合、全文インデックスは現在実際に存在するフィールドのみを検索対象とします。そのため、JSON やプレーンテキストのログの場合は、以下の方法で必要なフィールドを抽出してください。
ログフィールドの抽出¶
全文インデックスは、ログ内にすでに存在する業務フィールドをインデックス化しますが、message 内の内容を自動的に解析して分割することはありません。元のログがまだ JSON の一塊やプレーンテキストである場合は、DataKit または Pipeline を使用して内容を構造化フィールドとして抽出できます。
フィールド抽出が完了した後、元の message を保持するかどうかは、実際の要件によって決まります。
- 完全な元のテキストを確認する必要がある場合や、従来の使用習慣との互換性が必要な場合は、
messageを保持できます。 - 十分な構造化フィールドがすでにあり、元のテキストを保存する必要がなくなった場合は、
messageを削除できます。 messageを保持するかどうかに関係なく、抽出された業務フィールドは全文インデックスの対象となります。
DataKit を使用した JSON フィールドの抽出¶
各行が標準の JSON オブジェクトであり、すべてのトップレベルフィールドを直接抽出したいログに適しています。DataKit 2.9.0 以降では、json_as_fields を有効にできます。
これを有効にすると、DataKit は文字デコード、ANSI クリーンアップ、複数行マージの後、JSON ルートオブジェクトのトップレベルのプロパティをログフィールドに変換してから、Pipeline を実行します。
ホストログ収集¶
logging.conf を編集します。
[[inputs.logging]]
logfiles = ["/var/log/order/*.json"]
source = "order"
service = "order-api"
json_as_fields = true
設定を保存したら、DataKit を再起動 します。
Kubernetes コンテナログ収集¶
Pod Annotation を使用して、特定のコンテナに対して JSON フィールドモードを有効にできます。
metadata:
annotations:
datakit/order-api.logs: >-
[{"source":"order","service":"order-api","json_as_fields":true}]
ここで、order-api はコンテナ名です。コンテナ環境変数 DATAKIT_LOGS_CONFIG でも同じ JSON 設定を使用できます。
コンテナ設定の制限
json_as_fields は現在、コンテナ環境変数および Pod Annotation/Label での JSON ログ設定のみをサポートしており、ClusterLoggingConfig CRD はサポートしていません。
Log Streaming¶
logstreaming.conf で有効にします。
json_as_fields はコレクター設定であり、HTTP URL パラメーターではありません。この設定は influxdb、firelens、firehose タイプには適用されません。
抽出結果¶
元のログ:
{"timestamp":"2026-08-18T10:00:00+08:00","level":"INFO","service":"order-api","trace_id":"8d4f2a","order_id":"O-1001","amount":128.5,"labels":{"channel":"web"}}
変換後:
timestamp、level、service、trace_id、order_id、amountは独立したフィールドになります。labelsオブジェクトはコンパクトな JSON 文字列として保存されます。- DataKit は元の JSON 全体を保存する
messageを追加で生成しません。 - 元の JSON 自体に
messageが含まれている場合、そのフィールドは通常どおり保持されます。
主要なフィールド変換ルールは次のとおりです。
- トップレベルの文字列、ブール値、整数、小数は型を保持します。オブジェクトと配列はコンパクトな JSON 文字列として保存されます。
nullは無視されます。 - 不正な JSON、ルートノードがオブジェクトでない場合、有効なフィールドがない場合は、元の
messageにフォールバックします。 - フィールド名の
.は_に変換され、改行はスペースに変換されます。フィールド名の最大長は 256 バイトです。 - 1 つのログエントリあたり最大 1024 個のフィールド(タグは含まない)を保持できます。
- JSON フィールドは、コレクター内の同じ名前のタグまたはフィールドを上書きします。
- JSON 内の
time、source、date、storage_indexは、それぞれjson_time、json_source、json_date、json_storage_indexに名前が変更されます。
完全なルールについては、JSON フィールドモード を参照してください。
Pipeline を使用したフィールドの抽出¶
次のような場合に適しています。
- 一部のフィールドのみを抽出する必要がある。
- フィールドの名前変更や変換が必要。
- ログが標準 JSON ではない。
- 既存の Pipeline によるクレンジングフローがあり、それを引き続き使用したい。
すべてのトップレベルスカラーフィールドの抽出¶
DataKit 2.2.0 以降では、json_all() を使用できます。
# 元データ:
# {"service":"order-api","status":"info","trace_id":"8d4f2a","order_id":"O-1001","amount":128.5}
json_all(_, key_patterns=["*"])
処理後、service、status、trace_id、order_id、amount などの独立したフィールドが得られます。
json_all() は、トップレベルの文字列、数値、ブール値のみを抽出します。オブジェクトや配列を再帰的に展開したり、null を保存したりすることはありません。include_keys と key_patterns の両方が設定されていない場合、フィールドは抽出されません。すべてのトップレベルのスカラーフィールドを抽出する必要がある場合は、明示的に key_patterns=["*"] を設定する必要があります。
特定のフィールドのみの抽出¶
この方法では、全文インデックスに入るフィールドの範囲を制御したり、異なるログのフィールドを同じ名前に統一したりできます。
オブジェクトや配列は json_all() では抽出されません。このような内容を保持する必要がある場合は、json() を使用してフィールドを指定して抽出します。抽出結果は JSON 文字列として保存されます。
フィールド抽出後の message の削除¶
Pipeline を使用してフィールドを抽出する場合、元のログはデフォルトで message に保持されます。構造化フィールドがすでに表示やクエリの要件を満たしている場合は、フィールド抽出の完了後に drop_origin_data() を呼び出して、元の内容を保存しないようにできます。
特定のフィールドを抽出した後に削除することもできます。
json(_, service)
json(_, level, status)
json(_, trace_id)
json(_, order_id)
json(_, amount)
drop_origin_data()
JSON 自体に message が含まれており、そのフィールドも抽出された場合は、必要に応じて保持または削除できます。明確に不要な場合は、次のようにします。
3 つの関数の役割は異なります。
drop_origin_data():初期化時に保存された元のテキストを出力しなくなります。ログエントリ自体は引き続きアップロードされます。drop_key(message):すでに抽出されたmessageフィールドを削除します。drop():ログエントリ全体を破棄します。ログはアップロードされません。messageの削除には使用できません。
drop() を message の削除に使用しないでください
drop() は、現在のログを破棄対象としてマークします。Pipeline の実行が終了すると、ログエントリ全体がアップロードされなくなります。
詳しい構文については、json()、json_all()、drop_origin_data()、drop_key() を参照してください。
Pipeline のローカル検証¶
Pipeline スクリプトを保存した後、DataKit がインストールされているホストで以下を実行できます。
datakit pipeline -P full_line_json.p \
-T '{"service":"order-api","status":"info","trace_id":"8d4f2a","order_id":"O-1001","amount":128.5}'
出力が次の期待に沿っているか確認してください。
- 検索に必要なフィールドがすべて抽出されている。
drop_origin_data()を設定した場合、元のmessageが削除されている。- ログが
drop: trueとしてマークされていない。 statusやログ時刻などのフィールドが業務上の期待に沿っている。
よくある質問¶
全文インデックスでは message を削除する必要がありますか?¶
いいえ。message が存在する場合、システムはそれを通常の業務フィールドとして variant に書き込み、message に対して個別に全文インデックスを作成することはありません。message を削除するかどうかは、元の内容の保持と表示の要件に基づいて決定する必要があります。
全文インデックスを有効にしたのに、message 内の JSON フィールドが検索できません。¶
JSON の一塊がまだ message の文字列内容としてのみ存在する場合、その中のプロパティは独立した業務フィールドではありません。message 内のテキストを検索することはできますが、これらのプロパティを直接フィールドフィルタリングや集計に使用することはできません。DataKit または Pipeline を使用して、必要なフィールドを事前に抽出することをお勧めします。
message がない場合、ログエクスプローラーは内容をどのように表示しますか?¶
ログに message が存在しない場合、ログエクスプローラーは現在のログの業務フィールドを組み合わせてログ内容を表示します。システムフィールドはログ内容の一部としては表示されません。
同じインデックスに、message があるログとないログを同時に存在させることはできますか?¶
はい。両方のタイプのログは、統一されたルールに従って業務フィールドを variant に書き込み、variant が全文インデックスの対象となります。
全文インデックスでシステムフィールドを検索できますか?¶
いいえ。全文インデックスには業務フィールドのみが含まれ、システムフィールドは含まれません。システムフィールドは、フィールドフィルタリングなどを通じて引き続きクエリできます。