From 07bd6aa6a5fb37fb2e9c33fc4bda63ae9fb43914 Mon Sep 17 00:00:00 2001 From: Shinsuke Sugaya Date: Sat, 28 Dec 2024 12:00:35 +0900 Subject: [PATCH] #2862 Add comprehensive Javadoc comments and refine SearchLogHelper structure --- .../codelibs/fess/helper/SearchLogHelper.java | 172 ++++++++++++++++-- 1 file changed, 157 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java b/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java index fdbaa3d50..cb45378c6 100644 --- a/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java +++ b/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java @@ -67,25 +67,39 @@ import jakarta.annotation.PostConstruct; +/** + * Helper class for managing search logs. + */ public class SearchLogHelper { private static final Logger logger = LogManager.getLogger(SearchLogHelper.class); - protected long userCheckInterval = 10 * 60 * 1000L;// 10 min + /** Interval for checking user information in milliseconds (default: 10 minutes). */ + protected long userCheckInterval = 10 * 60 * 1000L; // 10 min + /** Maximum size of the user information cache. */ protected int userInfoCacheSize = 10000; + /** Queue for storing search logs. */ protected Queue searchLogQueue = new ConcurrentLinkedQueue<>(); + /** Queue for storing click logs. */ protected Queue clickLogQueue = new ConcurrentLinkedQueue<>(); + /** Cache for storing user information. */ protected LoadingCache userInfoCache; + /** Name of the logger for search logs. */ protected String loggerName = "fess.log.searchlog"; + /** Logger for search logs. */ protected Logger searchLogLogger = null; + /** ObjectMapper for JSON processing. */ protected ObjectMapper objectMapper = new ObjectMapper(); + /** + * Initializes the SearchLogHelper. + */ @PostConstruct public void init() { if (logger.isDebugEnabled()) { @@ -103,6 +117,17 @@ public UserInfo load(final String key) throws Exception { searchLogLogger = LogManager.getLogger(loggerName); } + /** + * Adds a search log to the queue. + * + * @param params The search request parameters. + * @param requestedTime The time the search was requested. + * @param queryId The ID of the search query. + * @param query The search query. + * @param pageStart The starting page number. + * @param pageSize The size of the page. + * @param queryResponseList The list of query responses. + */ public void addSearchLog(final SearchRequestParams params, final LocalDateTime requestedTime, final String queryId, final String query, final int pageStart, final int pageSize, final QueryResponseList queryResponseList) { @@ -188,6 +213,12 @@ public void addSearchLog(final SearchRequestParams params, final LocalDateTime r searchLogQueue.add(searchLog); } + /** + * Adds documents in the response to the search log. + * + * @param queryResponseList The list of query responses. + * @param searchLog The search log. + */ protected void addDocumentsInResponse(final QueryResponseList queryResponseList, final SearchLog searchLog) { if (ComponentUtil.getFessConfig().isLoggingSearchDocsEnabled()) { queryResponseList.stream().forEach(res -> { @@ -198,27 +229,47 @@ protected void addDocumentsInResponse(final QueryResponseList queryResponseList, } } + /** + * Adds a click log to the queue. + * + * @param clickLog The click log. + */ public void addClickLog(final ClickLog clickLog) { clickLogQueue.add(clickLog); } + /** + * Stores search logs from the queue. + */ public void storeSearchLog() { storeSearchLogFromQueue(); storeClickLogFromQueue(); } + /** + * Stores click logs from the queue. + */ protected void storeClickLogFromQueue() { if (!clickLogQueue.isEmpty()) { processClickLogQueue(clickLogQueue); } } + /** + * Stores search logs from the queue. + */ protected void storeSearchLogFromQueue() { if (!searchLogQueue.isEmpty()) { processSearchLogQueue(searchLogQueue); } } + /** + * Gets the click count for a URL. + * + * @param url The URL. + * @return The click count. + */ public int getClickCount(final String url) { final ClickLogBhv clickLogBhv = ComponentUtil.getComponent(ClickLogBhv.class); return clickLogBhv.selectCount(cb -> { @@ -226,6 +277,12 @@ public int getClickCount(final String url) { }); } + /** + * Gets the favorite count for a URL. + * + * @param url The URL. + * @return The favorite count. + */ public long getFavoriteCount(final String url) { final FavoriteLogBhv favoriteLogBhv = ComponentUtil.getComponent(FavoriteLogBhv.class); return favoriteLogBhv.selectCount(cb -> { @@ -233,6 +290,12 @@ public long getFavoriteCount(final String url) { }); } + /** + * Stores user information. + * + * @param userCode The user code. + * @return The user information. + */ protected UserInfo storeUserInfo(final String userCode) { final UserInfoBhv userInfoBhv = ComponentUtil.getComponent(UserInfoBhv.class); @@ -251,6 +314,12 @@ protected UserInfo storeUserInfo(final String userCode) { return userInfo; } + /** + * Gets user information. + * + * @param userCode The user code. + * @return The user information. + */ public OptionalEntity getUserInfo(final String userCode) { if (StringUtil.isNotBlank(userCode)) { try { @@ -264,6 +333,11 @@ public OptionalEntity getUserInfo(final String userCode) { return OptionalEntity.empty(); } + /** + * Processes the search log queue. + * + * @param queue The search log queue. + */ protected void processSearchLogQueue(final Queue queue) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final String value = fessConfig.getPurgeByBots(); @@ -274,7 +348,7 @@ protected void processSearchLogQueue(final Queue queue) { botNames = value.split(","); } - final int batchSize = ComponentUtil.getFessConfig().getSearchlogProcessBatchSizeAsInteger(); + final int batchSize = fessConfig.getSearchlogProcessBatchSizeAsInteger(); final List searchLogList = new ArrayList<>(); final Map userInfoMap = new HashMap<>(); @@ -310,20 +384,34 @@ protected void processSearchLogQueue(final Queue queue) { } } - private void processSearchLog(final List searchLogList) { + /** + * Processes the search log list. + * + * @param searchLogList The search log list. + */ + protected void processSearchLog(final List searchLogList) { if (!searchLogList.isEmpty()) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); + // write log + if (fessConfig.isLoggingSearchUseLogfile()) { + searchLogList.forEach(this::writeSearchLogEvent); + } + // insert search log storeSearchLogList(searchLogList); + // update suggest index if (fessConfig.isSuggestSearchLog()) { final SuggestHelper suggestHelper = ComponentUtil.getSuggestHelper(); suggestHelper.indexFromSearchLog(searchLogList); } - if (fessConfig.isLoggingSearchUseLogfile()) { - searchLogList.forEach(this::writeSearchLogEvent); - } } } + /** + * Processes user information logs. + * + * @param searchLogList The search log list. + * @param userInfoMap The user information map. + */ protected void processUserInfoLog(final List searchLogList, final Map userInfoMap) { if (!userInfoMap.isEmpty()) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); @@ -341,20 +429,28 @@ protected void processUserInfoLog(final List searchLogList, final Map updateList.add(entity); insertList.remove(entity); }); + // write log + if (fessConfig.isLoggingSearchUseLogfile()) { + insertList.forEach(this::writeSearchLogEvent); + updateList.forEach(this::writeSearchLogEvent); + } + // insert/update user info userInfoBhv.batchInsert(insertList); userInfoBhv.batchUpdate(updateList); + // update search log searchLogList.stream().forEach(searchLog -> { searchLog.getUserInfo().ifPresent(userInfo -> { searchLog.setUserInfoId(userInfo.getId()); }); }); - if (fessConfig.isLoggingSearchUseLogfile()) { - insertList.forEach(this::writeSearchLogEvent); - updateList.forEach(this::writeSearchLogEvent); - } } } + /** + * Stores a list of search logs. + * + * @param searchLogList The search log list. + */ protected void storeSearchLogList(final List searchLogList) { final SearchLogBhv searchLogBhv = ComponentUtil.getComponent(SearchLogBhv.class); searchLogBhv.batchUpdate(searchLogList, op -> { @@ -362,6 +458,11 @@ protected void storeSearchLogList(final List searchLogList) { }); } + /** + * Processes the click log queue. + * + * @param queue The click log queue. + */ protected void processClickLogQueue(final Queue queue) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final int batchSize = fessConfig.getSearchlogProcessBatchSizeAsInteger(); @@ -405,6 +506,11 @@ protected void processClickLogQueue(final Queue queue) { } } + /** + * Updates the click field in the index. + * + * @param clickCountMap The click count map. + */ protected void updateClickFieldInIndex(final Map clickCountMap) { if (!clickCountMap.isEmpty()) { final SearchHelper searchHelper = ComponentUtil.getSearchHelper(); @@ -440,21 +546,30 @@ protected void updateClickFieldInIndex(final Map clickCountMap) } } + /** + * Processes a list of click logs. + * + * @param clickLogList The click log list. + */ protected void processClickLog(final List clickLogList) { if (!clickLogList.isEmpty()) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); + if (fessConfig.isLoggingSearchUseLogfile()) { + clickLogList.forEach(this::writeSearchLogEvent); + } try { - final ClickLogBhv clickLogBhv = ComponentUtil.getComponent(ClickLogBhv.class); - clickLogBhv.batchInsert(clickLogList); + ComponentUtil.getComponent(ClickLogBhv.class).batchInsert(clickLogList); } catch (final Exception e) { logger.warn("Failed to insert: {}", clickLogList, e); } - if (fessConfig.isLoggingSearchUseLogfile()) { - clickLogList.forEach(this::writeSearchLogEvent); - } } } + /** + * Writes a search log event. + * + * @param event The search log event. + */ public void writeSearchLogEvent(final SearchLogEvent event) { try { final Map source = toSource(event); @@ -464,6 +579,12 @@ public void writeSearchLogEvent(final SearchLogEvent event) { } } + /** + * Converts a search log event to a source map. + * + * @param searchLogEvent The search log event. + * @return The source map. + */ protected Map toSource(final SearchLogEvent searchLogEvent) { final Map source = toLowerHyphen(searchLogEvent.toSource()); source.put("_id", searchLogEvent.getId()); @@ -472,6 +593,12 @@ protected Map toSource(final SearchLogEvent searchLogEvent) { return source; } + /** + * Converts a map to lower hyphen case. + * + * @param source The source map. + * @return The converted map. + */ protected Map toLowerHyphen(final Map source) { return source.entrySet().stream() .collect(Collectors.toMap(e -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.getKey()), e -> { @@ -485,14 +612,29 @@ protected Map toLowerHyphen(final Map source) { })); } + /** + * Sets the user check interval. + * + * @param userCheckInterval The user check interval. + */ public void setUserCheckInterval(final long userCheckInterval) { this.userCheckInterval = userCheckInterval; } + /** + * Sets the user information cache size. + * + * @param userInfoCacheSize The user information cache size. + */ public void setUserInfoCacheSize(final int userInfoCacheSize) { this.userInfoCacheSize = userInfoCacheSize; } + /** + * Sets the logger name. + * + * @param loggerName The logger name. + */ public void setLoggerName(final String loggerName) { this.loggerName = loggerName; }