Fessのインデックスエクスポートで保存先と実出力件数を確認する

Fessのインデックスエクスポートでは、保存先に書き込めなくてもジョブログが正常終了となり、取得した件数が出力件数として表示される場合がありました。保存先の事前検査と、実際に書き出した件数の集計を追加する修正がマージされました。

既存のHTML/JSONエクスポート機能に対する運用上の改善です。

保存先の初期値

開発版で確認した設定は次のとおりです。

設定初期値
index.export.path/var/lib/fess/export
index.export.formathtml
index.export.exclude.fieldscache,tag
index.export.scroll.size100

保存先の初期値は今回の修正でも変わりません。ZIP版を一般ユーザーで動かす場合、/var/lib/fess/exportへ書き込めないことがあります。Fess実行ユーザーが書き込める専用ディレクトリを用意し、環境に合わせて設定してください。

index.export.path=/home/fess/export

これは例のパスです。Fessプロセスから見える場所と権限を確認し、設定を反映してジョブを実行します。

修正後の結果の読み方

修正後は検索開始前にディレクトリを作成し、一時ファイルの作成・削除で書き込みを確認します。失敗するとindex.export.pathと保存先を含むエラーでジョブが失敗します。

一方、処理途中で個々の文書を書き出せない場合は、その件数を結果へ追加します。Exported N documents.は実際に書けた件数となり、URLがない文書などのスキップも出力件数へ含めません。事前検査の成功は全ファイルの成功を保証しないので、未出力件数とログを合わせて確認してください。

スケジュールの書き方

関連文書PR #599では、cronを5項目の形式へ訂正しています。毎日午前2時なら次の式です。

0 2 * * *

順番は「分 時 日 月 曜日」です。秒を含む6項目やQuartzの?は使いません。実行時刻はFess側のタイムゾーンに合わせて確認してください。

この変更はバックアップ復元機能ではありません。書き出し先の容量や古いファイルの整理も別途運用し、終了状態だけでなく実ファイルの有無と内容を確認してください。

関連PR

Fessのv2 APIクライアントでJSON本文と応答型を確認する

Fessのv2 APIを自作クライアントから呼ぶとき、正しいJSONでも本文の最上位が配列やnullだと受け付けられません。JSON本文の検証修正と、実際の応答に合わせたOpenAPI・リファレンスの訂正をまとめて確認します。

JSON本文はUTF-8のオブジェクトにする

ログイン、クリック記録、パスワード変更、タグ、お気に入り、チャットなど、共通のJSON本文読み込みを使うAPIが対象です。Content-Type: application/jsonを指定し、文字コードを明示する場合もUTF-8を使います。

修正後は最上位のnull、配列、文字列、数値、真偽値をHTTP 400、invalid_requestとして拒否します。オブジェクト内のnull、たとえば{"a":null}はJSONの構造として読み取れますが、各APIの必須項目の検証は別に実行されます。

不正なUTF-8バイト列も400になります。以前のように代替文字へ置き換えてタグ名などを保存しません。先頭のUTF-8 BOMは読み取り時に除去します。0バイトの本文は空オブジェクト相当として読み取る仕様を維持し、空白だけの本文や未入力の必須フィールドまで成功とするものではありません。

この検証を有効にする設定は追加していません。各APIの認証、CSRF、本文サイズ制限は従来の条件に従い、サイズ上限は呼び出すAPIで決まります。400では本文を修正し、文字コードやContent-Typeによる415、サイズによる413とは区別して扱います。

生成クライアントの数値型を確認する

検索ヒットのcontent_lengthとboostは、クローラーが保存した文書では"9894"、"1.0"のような文字列です。OpenAPIで整数・数値とされていた定義を文字列へ訂正しました。管理用documents APIから登録した文書ではJSON数値を持つ場合もあるため、実データを確認し、必要ならクライアント側で両形式を扱います。

検索語がない場合のhighlight_paramsはnullになり得ます。更新された定義からクライアントを再生成し、検索語なしの応答もデシリアライズできるか確認してください。定義上の型が変わっても、サーバーがここで既存文書を変換するわけではありません。

UI設定と認証エラーにも対応する

/api/v2/ui/configのfeatures.login_linkは真偽値だけでなく、SSO利用時には相対URLの"sso/"になる場合があります。default_label_valuesやdefault_sortは画面の初期選択用で、/api/v2/searchが自動適用する値ではありません。

サジェストのnumの初期値は10で、page_sizeは実際に返された語数です。語数が要求より少なくても異常と決め付けないでください。各APIはログイン必須設定や無効なトークンなどの条件で401を返し、デコード不能なクエリ文字列では処理前に400になり得ます。

実環境に近い検索文書、検索語なし、認証失敗、SSO設定の組み合わせでクライアントを確認すると、正常系だけでは見つからない型の不一致を減らせます。

関連PR

Fessのデータクロールで最後の一括登録失敗を確認しやすくする

データクロールでは、取得できた文書が検索エンジンのマッピングに合わず、一括登録の最後のバッチだけが失敗することがあります。Fessで、文書単位の失敗理由をWARNへ出す変更と、最終コミットの失敗をクロールログ・障害URLへ記録する変更がマージされました。

文書単位の拒否理由

従来は一括登録で拒否された文書の情報がDEBUG中心で、通常運用のログでは対象や理由が分かりにくい状態でした。修正後は、拒否された各文書についてURL、ID、ステータス、エラー種別、理由をWARNに記録します。

理由の長さは500文字までに制限します。マッピングエラーが付加するフィールド値のプレビューはログから除きます。ただし、#3616と#3624だけでは、後続の例外メッセージや数値変換の理由にフィールド値が残る経路があります。#3643はこれらも除去する提案ですが、今回の取得時点では未マージです。ログと障害URLに文書内容が絶対に含まれないとは扱わず、共有前に内容を確認してください。設定項目を追加して有効化する方式ではなく、修正された処理のログ出力が変わります。WARNが出力されるログレベルで運用することが必要です。

送信文書数と応答件数が一致せずURLを対応付けられない場合、URLはnullとなります。文書IDなど他の情報で調べます。文書単位の問題としてWARNにしているため、この出力だけでERROR通知が発生するとは限りません。

最終コミット失敗も記録する

データストアの処理終了時には、まだバッファーに残った文書をコミットします。この処理で例外が発生すると、修正前はクロールスレッドの未捕捉例外となり、クロールログや障害URLへ記録されない場合がありました。

修正後は例外を捕捉し、ERRORログと障害URLに記録します。最終コミットが失敗した場合は、その後の古い文書削除を実行しません。登録に失敗した文書が置き換えるはずだった既存文書を、削除処理で消さないためです。

調査と再実行

取得件数と登録件数が合わない場合は、WARNの文書ID・エラー種別、最終コミットのERROR、該当データ設定の障害URLを確認します。たとえばmapper_parsing_exceptionなら、送信した値の型と検索インデックスのマッピングを比較します。型や変換処理を直してからクロールを再実行します。

文書単位のWARN処理自体が、各拒否文書をすべて障害URLとして登録するわけではありません。最終コミットの失敗記録はデータクロール設定の単位です。また、今回の変更は失敗の可視化であり、自動再試行やマッピングの修復を追加するものではありません。

関連PR