コンテンツにスキップ

検索・クエリ (Search)

Search は CSIRT-Pro のログ分析の中心となる機能です。

問い合わせ言語 PRQL を使って、取り込んだログを検索・集計・可視化できます。 抽出はクエリ実行時に行われるため、取り込み済みのログに後からフィールドの取り出し方を変えられます。1


画面構成

Search 画面は次の要素で構成されています。

Search 画面の全体レイアウト 図: Search 画面(稼働中ビルドから取得)。検索対象組織と Pipeline の選択、Time Range、検索バー、Fields と Filters、ヒストグラムで構成されています。

  1. クエリエディタ:PRQL クエリを入力するエディタ。シンタックスハイライトとオートコンプリートに対応します。
  2. 時間範囲セレクタ:検索対象の時間範囲を指定します(画面右上)。
  3. 可視化エリア:クエリ結果をチャートで表示します。
  4. データテーブル:クエリ結果を表形式で表示します(ページネーション対応)。
  5. フィールドリスト:利用可能なフィールドの一覧を左パネルに表示します。

クエリエディタのクローズアップ 図: PRQL クエリエディタ。シンタックスハイライトとオートコンプリート


PRQL クエリ言語

CSIRT-Pro は PRQL (Pipelined Relational Query Language) を採用しています。

パイプライン形式で、処理が上から下へ順に流れる書き方をします。

基本構文

from `<pipeline_name>`
filter <条件>
select {<フィールド>}
sort {<ソート条件>}
take <件数>

クエリ例

全件取得

from `firewall_logs`

条件フィルタ

from `firewall_logs`
filter action == "DENY"
filter src_ip == "192.168.1.100"

時間範囲フィルタ

from `firewall_logs`
filter __time > @2025-01-01
filter __time < @2025-01-31

部分一致検索

from `auth_logs`
filter message ~= "failed"

フィールド選択

from `firewall_logs`
select {__time, src_ip, dst_ip, action, bytes}

集計

from `firewall_logs`
filter action == "DENY"
group {src_ip} (
  aggregate {cnt = count this}
)
sort {-cnt}
take 10

集計クエリの実行結果 図: 集計クエリの実行結果。棒グラフとデータテーブル

ソート

from `firewall_logs`
sort {-__time}
take 100

ショートカット

Ctrl + Enter でクエリを実行できます。

集計クエリの所要時間

特定の値を絞り込む検索は数秒以内で返ることが多い一方、生ログ全体を走査する大規模な集計(group を含むクエリ)は対象が大きいほど時間がかかります。 schema-on-read 方式では、検索時に生ログからフィールドを抽出してから集計するためです。 時間範囲を絞る、対象 Pipeline を限定する、filter を先に置くことで走査量を減らせます。


時間範囲の指定

時間範囲セレクタから、検索対象期間を指定できます。

時間範囲セレクタ 図: 時間範囲セレクタ。プリセットとカスタム範囲

プリセット 期間
Last 15 minutes 直近 15 分
Last 30 minutes 直近 30 分
Last 1 hour 直近 1 時間
Last 24 hours 直近 24 時間
Last 7 days 直近 7 日間
Custom カスタム日時範囲

Custom(カスタム範囲)の使い方

  1. 時間範囲セレクタで「Custom」を選択します。
  2. 開始日時と終了日時をカレンダーから選択します。
  3. 「Apply」をクリックして適用します。

可視化タイプ

クエリ結果は次の可視化タイプで表示できます。 チャートエリアのコンテキストメニューから種類を切り替えられます。

グラフ

タイプ 用途
Bar(棒) カテゴリ別の件数・量の比較
Horizontal Bar(横棒) ラベルが長いカテゴリの比較
Stacked Bar(積み上げ棒) 内訳を積み上げ、全体と構成を同時に表示
Line(折れ線) 時系列トレンドの表示
Area(エリア) 折れ線の下を塗り、推移を強調
Timeline(タイムライン) 時系列ヒストグラム。自動バケッティングとドリルダウンに対応
Pie(円) 割合・構成比の表示
Doughnut(ドーナツ) 割合表示(中央にサマリーを表示)
Polar Area 放射状の比較表示
Radar(レーダー) 複数軸での比較
Scatter(散布図) 2 軸の相関・分布
Bubble(バブル) 3 つ目の値を点の大きさで表す散布図
Heatmap(ヒートマップ) 2 次元の密度・強弱を色で表現

指標・表・関係

タイプ 用途
KPI 単一の重要指標。前月比(増減)を併記できる
Gauge(ゲージ) 目標に対する達成度。半円(既定)と横棒の 2 スタイル
Data Table(データテーブル) 明細の表形式表示
Service Graph(サービスグラフ) ノードとリンクによる関係・通信の可視化
Case(ケース) 保存済みの Case View をパネルとして埋め込み

レポート要素(Markdown / PDF 帳票向け)

タイプ 用途
Markdown テンプレートによる注釈・サマリー・帳票本文(後述)
Index(目次) レポートの目次
Cover(表紙) PDF 帳票の表紙
Back Cover(裏表紙) PDF 帳票の裏表紙

系列ごとの色指定

系列名やカテゴリ名と色(hex)の対応を指定すると、既定パレットより優先してその色で描画できます。 たとえば critical を赤、high をオレンジに固定できます。


Markdown 可視化(Jinja2 テンプレート)

Markdown タイプは、Markdown に Jinja2 互換のテンプレート構文を組み合わせて、注釈やサマリー、PDF 帳票の本文を動的に生成します。 テンプレートはサーバ側で安全にレンダリングされます。

クエリ結果の埋め込み

テンプレートの中に query:名前 のコードブロックを置き、その中に PRQL を書くと、実行結果を {{ 名前 }} で参照できます。

```query:alerts
from `firewall_logs`
filter action == "DENY"
sort {-__time}
take 5
```

直近の DENY は **{{ alerts | length }} 件**です。

| 時刻 | 送信元 IP | 宛先 IP |
|---|---|---|
{% for row in alerts -%}
| {{ row.__time }} | {{ row.src_ip }} | {{ row.dst_ip }} |
{% endfor %}

取得結果は行(オブジェクト)の配列で、{{ 名前 }}{{ data.名前 }} の両方で参照できます。 query:名前 の中身をにすると、同じ名前で保存した可視化のデータを参照します。 取得用のコードブロックは、最終的な出力には残りません。

よく使う構文

  • 変数の出力:{{ 値 }}
  • 条件分岐:{% if 条件 %} … {% else %} … {% endif %}
  • 繰り返し:{% for row in 名前 %} … {% endfor %}
  • フィルタの適用:{{ 値 | フィルタ }}

組み込みフィルタ(抜粋)

一般的な Jinja2 フィルタ(length / default / join / upper など)に加え、次の独自フィルタを利用できます。

フィルタ 説明
percentage(total) 全体に対する百分率(文字列) {{ n | percentage(total) }}
safe_sum(field) / safe_avg(field) 配列の合計 / 平均 {{ alerts | safe_sum("bytes") }}
min_value(field) / max_value(field) 配列の最小 / 最大 {{ alerts | max_value("bytes") }}
count_by(field) 値ごとの件数を集計 {{ alerts | count_by("action") }}
pluck(field) 配列から指定フィールドを抽出 {{ alerts | pluck("src_ip") }}
get(key) オブジェクトからキーの値を取得 {{ row | get("src_ip") }}
subtract / multiply / divide 四則演算 {{ a | divide(b) }}
format_date(fmt) / add_days(n) 日時の書式整形 / n 日加算 {{ row.__time | format_date("%Y-%m-%d") }}
status_class / severity_class / severity_label ステータス・重要度の表示用クラス / ラベル {{ row.severity | severity_label }}
filesizeformat / wordcount / striptags / center / md_escape 単位整形 / 文字数 / タグ除去 / 中央寄せ / Markdown エスケープ {{ bytes | filesizeformat }}

組み込み関数

関数 説明
now() / today() 現在日時 / 当日(YYYY-MM-DD
coalesce(a, b, …) 最初の「未定義・空でない」値を返す(可変長)
line(文字, 長さ) / dots(長さ) / separator(種類, 長さ) 区切り線の生成
grid_item(タイトル, 値) グリッド表示用の HTML 断片

PDF 帳票の表紙・スタイル

Cover / Back Cover / Markdown では、テンプレートの先頭に json または css のコードブロックを置くと、背景画像(backgroundImage)や見出し(h1 / h2 / h3)のスタイルを指定できます。 レポートの表紙・裏表紙づくりに利用します。

制限事項

  • 他テンプレートの取り込み({% include %} / {% extends %})は使用できません。
  • 未定義の変数は空文字として扱われます(エラーにはなりません)。
  • 編集内容はおよそ 3 秒後にプレビューへ反映されます。
  • テンプレートに渡るデータは、配列で最大 200 件、入れ子の深さ 8 までに制限されます。

インタラクティブフィルタリング

フィールド値によるフィルタ

データテーブルのセル値をクリックすると、その値でフィルタを追加できます。

セルクリックによるフィルタリング 図: テーブルのセルをクリックしてフィルタを追加

  1. テーブルのセルをクリックします。
  2. コンテキストメニューから「フィルタに追加」を選択します。
  3. クエリに filter 句が自動追加されます。

Top 5 値の確認

フィールドリストのフィールド名を右クリックすると、そのフィールドの上位 5 件の値を確認できます。

フィールドリストの Top 5 表示 図: フィールドリストから Top 5 値をプレビュー


可視化の保存と再利用

作成したクエリと可視化設定を保存して、後から再利用できます。

保存方法

可視化の保存ダイアログ 図: 可視化の保存ダイアログ

  1. クエリを実行して結果を確認します。
  2. 「保存」ボタンをクリックします。
  3. タイトルを入力して保存します。

読み込み方法

  1. 可視化ドロップダウンから保存済みの可視化を選択します。
  2. クエリと可視化設定が復元されます。

JSON エクスポート / インポート

可視化設定を JSON ファイルとしてエクスポートし、他の環境にインポートすることもできます。


データ転送形式

Search API は、大量データの転送効率を高めるため、レスポンスを列指向のバイナリ形式で返します。 Web UI では自動的にデシリアライズされて表示されます。

API から直接利用する場合は、検索 API リファレンス を参照してください。


  1. 生ログを保持したまま、検索時に取り込み定義(パース)に従ってフィールドを抽出する schema-on-read 方式を採用しています。スキーマを後から変更でき、移行や取り込みが容易になる一方、列単位であらかじめ型付けした構成に比べて大規模集計は遅くなります。