diff --git a/src/main/java/org/codelibs/fess/es/log/exentity/SearchLog.java b/src/main/java/org/codelibs/fess/es/log/exentity/SearchLog.java index 018de6dd1..16008064b 100644 --- a/src/main/java/org/codelibs/fess/es/log/exentity/SearchLog.java +++ b/src/main/java/org/codelibs/fess/es/log/exentity/SearchLog.java @@ -90,6 +90,9 @@ public class SearchLog extends BsSearchLog { public void setUserInfo(final OptionalEntity userInfo) { this.userInfo = userInfo; + userInfo.ifPresent(e -> { + super.setUserInfoId(e.getId()); + }); } public List> getSearchFieldLogList() { diff --git a/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java b/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java index f183b102a..a82f42356 100644 --- a/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java +++ b/src/main/java/org/codelibs/fess/helper/SearchLogHelper.java @@ -25,12 +25,13 @@ import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.codelibs.core.collection.LruHashMap; import org.codelibs.core.lang.StringUtil; import org.codelibs.fess.Constants; import org.codelibs.fess.app.service.SearchService; @@ -48,6 +49,7 @@ import org.codelibs.fess.mylasta.direction.FessConfig; import org.codelibs.fess.util.ComponentUtil; import org.codelibs.fess.util.DocumentUtil; import org.codelibs.fess.util.QueryResponseList; +import org.dbflute.optional.OptionalEntity; import org.dbflute.optional.OptionalThing; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.script.Script; @@ -55,22 +57,34 @@ import org.lastaflute.web.util.LaRequestUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + public class SearchLogHelper { private static final Logger logger = LoggerFactory.getLogger(SearchLogHelper.class); - protected long userCheckInterval = 5 * 60 * 1000L;// 5 min + protected long userCheckInterval = 10 * 60 * 1000L;// 10 min - protected int userInfoCacheSize = 1000; + protected int userInfoCacheSize = 10000; protected volatile Queue searchLogQueue = new ConcurrentLinkedQueue<>(); protected volatile Queue clickLogQueue = new ConcurrentLinkedQueue<>(); - protected Map userInfoCache; + protected LoadingCache userInfoCache; @PostConstruct public void init() { - userInfoCache = new LruHashMap<>(userInfoCacheSize); + userInfoCache = CacheBuilder.newBuilder()// + .maximumSize(userInfoCacheSize)// + .expireAfterWrite(userCheckInterval, TimeUnit.MILLISECONDS)// + .build(new CacheLoader() { + @Override + public UserInfo load(String key) throws Exception { + return storeUserInfo(key); + } + }); } public void addSearchLog(final SearchRequestParams params, final LocalDateTime requestedTime, final String queryId, final String query, @@ -84,6 +98,7 @@ public class SearchLogHelper { final String userCode = userInfoHelper.getUserCode(); if (userCode != null) { searchLog.setUserSessionId(userCode); + searchLog.setUserInfo(getUserInfo(userCode)); } } @@ -186,28 +201,35 @@ public class SearchLogHelper { }); } - public void updateUserInfo(final String userCode) { - final long current = System.currentTimeMillis(); - final Long time = userInfoCache.get(userCode); - if (time == null || current - time.longValue() > userCheckInterval) { + protected UserInfo storeUserInfo(final String userCode) { + final UserInfoBhv userInfoBhv = ComponentUtil.getComponent(UserInfoBhv.class); - final UserInfoBhv userInfoBhv = ComponentUtil.getComponent(UserInfoBhv.class); + final LocalDateTime now = ComponentUtil.getSystemHelper().getCurrentTimeAsLocalDateTime(); + final UserInfo userInfo = userInfoBhv.selectByPK(userCode).map(e -> { + e.setUpdatedAt(now); + return e; + }).orElseGet(() -> { + final UserInfo e = new UserInfo(); + e.setId(userCode); + e.setCreatedAt(now); + e.setUpdatedAt(now); + return e; + }); + new Thread(() -> userInfoBhv.insertOrUpdate(userInfo)).start(); + return userInfo; + } - final LocalDateTime now = ComponentUtil.getSystemHelper().getCurrentTimeAsLocalDateTime(); - userInfoBhv.selectByPK(userCode).ifPresent(userInfo -> { - userInfo.setUpdatedAt(now); - new Thread(() -> { - userInfoBhv.insertOrUpdate(userInfo); - }).start(); - }).orElse(() -> { - final UserInfo userInfo = new UserInfo(); - userInfo.setId(userCode); - userInfo.setCreatedAt(now); - userInfo.setUpdatedAt(now); - userInfoBhv.insert(userInfo); - }); - userInfoCache.put(userCode, current); + public OptionalEntity getUserInfo(final String userCode) { + if (StringUtil.isNotBlank(userCode)) { + try { + return OptionalEntity.of(userInfoCache.get(userCode)); + } catch (ExecutionException e) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to access UserInfo cache.", e); + } + } } + return OptionalEntity.empty(); } protected void processSearchLogQueue(final Queue queue) { @@ -274,7 +296,7 @@ public class SearchLogHelper { } } - private void storeSearchLogList(final List searchLogList) { + protected void storeSearchLogList(final List searchLogList) { final SearchLogBhv searchLogBhv = ComponentUtil.getComponent(SearchLogBhv.class); searchLogBhv.batchUpdate(searchLogList, op -> { op.setRefreshPolicy(Constants.TRUE); diff --git a/src/main/java/org/codelibs/fess/helper/UserInfoHelper.java b/src/main/java/org/codelibs/fess/helper/UserInfoHelper.java index 413bd5de8..a6d3c6a14 100644 --- a/src/main/java/org/codelibs/fess/helper/UserInfoHelper.java +++ b/src/main/java/org/codelibs/fess/helper/UserInfoHelper.java @@ -129,7 +129,7 @@ public class UserInfoHelper { } protected void updateUserSessionId(final String userCode) { - ComponentUtil.getSearchLogHelper().updateUserInfo(userCode); + ComponentUtil.getSearchLogHelper().getUserInfo(userCode); final HttpServletRequest request = LaRequestUtil.getRequest(); request.setAttribute(Constants.USER_CODE, userCode);