FessではPurgeLogJobによって古い検索ログが定期的にパージされる仕組みがあるが、クリックログとお気に入りログは対象外で、OpenSearch上に無制限に蓄積され続けていた。今回、これらのログも検索ログと同じ保持日数でパージされるようにした。
背景
Fessは検索体験の分析のために、以下の3種類のログをOpenSearchに記録する。
- 検索ログ(Search Log) — 検索クエリやヒット件数などの情報
- クリックログ(Click Log) — 検索結果がクリックされた際の情報
- お気に入りログ(Favorite Log) — 検索結果がお気に入り登録された際の情報
クリックログとお気に入りログは、検索ログを親データとする子データとして扱われる。つまり、親となる検索ログが削除されても、子であるクリックログ・お気に入りログは残り続けるため、親を参照できない孤立したデータが蓄積していく状態となっていた。
PurgeLogJobはこれまで検索ログ・ジョブログ・ユーザー情報ログ・クロール情報をパージしていたが、クリックログとお気に入りログは対象外だったため、長期運用しているFess環境ではインデックスが無制限に膨らむ問題があった。
変更内容
SearchLogServiceに削除メソッドを追加
SearchLogServiceに、クリックログとお気に入りログを日数指定で削除するメソッドを追加した。
public void deleteClickLogBefore(final int days) {
clickLogBhv.queryDelete(cb -> {
cb.query().setRequestedAt_LessEqual(
systemHelper.getCurrentTimeAsLocalDateTime().minusDays(days));
});
}
public void deleteFavoriteLogBefore(final int days) {
favoriteLogBhv.queryDelete(cb -> {
cb.query().setCreatedAt_LessEqual(
systemHelper.getCurrentTimeAsLocalDateTime().minusDays(days));
});
}
クリックログはrequestedAt(検索リクエスト日時)、お気に入りログはcreatedAt(作成日時)を基準に、指定日数より古いドキュメントを削除する。
PurgeLogJobにパージ処理を追加
PurgeLogJob.execute()の検索ログパージの直後に、クリックログとお気に入りログのパージ処理を追加した。
// purge click logs
try {
final int days = ComponentUtil.getFessConfig().getPurgeSearchLogDay();
if (days >= 0) {
searchLogService.deleteClickLogBefore(days);
} else {
resultBuf.append("Skipped to purge click logs.\n");
}
} catch (final Exception e) {
logger.error("Failed to purge click logs.", e);
resultBuf.append(e.getMessage()).append("\n");
}
お気に入りログ側もほぼ同じ実装となっている。例外が発生しても他のパージ処理に影響しないよう、それぞれ独立したtry-catchで囲んでいる。
保持日数は検索ログと共有
クリックログ・お気に入りログの保持日数には、専用の設定は新設せず、既存のpurge.searchlog.dayを共用する設計とした。
これは、前述のとおりクリックログとお気に入りログが検索ログの子データだからである。親の検索ログが消えた時点で参照元を失うため、検索ログと同じ保持期間でパージするのが自然な振る舞いとなる。
将来的に保持期間を個別に設定したくなった場合は、専用の設定プロパティを追加し、未指定時はpurge.searchlog.dayにフォールバックする形で拡張できる。
まとめ
Fess 15.6.0から、purge.searchlog.dayで指定した日数に基づいて、検索ログ・クリックログ・お気に入りログが同時にパージされるようになる。これまで長期運用でクリックログやお気に入りログが肥大化していた環境では、アップグレード後に古いデータが自動的に整理されるため、OpenSearchのストレージ負荷軽減が期待できる。