1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.app.service;
17
18 import java.nio.charset.StandardCharsets;
19 import java.time.LocalDateTime;
20 import java.time.ZoneId;
21 import java.time.ZoneOffset;
22 import java.time.format.DateTimeFormatter;
23 import java.util.Base64;
24 import java.util.HashMap;
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.stream.Collectors;
29
30 import javax.annotation.Resource;
31
32 import org.apache.logging.log4j.LogManager;
33 import org.apache.logging.log4j.Logger;
34 import org.codelibs.core.beans.util.BeanUtil;
35 import org.codelibs.core.lang.StringUtil;
36 import org.codelibs.fesen.search.aggregations.AggregationBuilders;
37 import org.codelibs.fesen.search.aggregations.BucketOrder;
38 import org.codelibs.fesen.search.aggregations.bucket.histogram.DateHistogramInterval;
39 import org.codelibs.fesen.search.aggregations.bucket.histogram.Histogram;
40 import org.codelibs.fesen.search.aggregations.bucket.terms.Terms;
41 import org.codelibs.fesen.search.aggregations.metrics.Avg;
42 import org.codelibs.fesen.search.aggregations.metrics.Cardinality;
43 import org.codelibs.fess.Constants;
44 import org.codelibs.fess.app.pager.SearchLogPager;
45 import org.codelibs.fess.es.log.allcommon.EsPagingResultBean;
46 import org.codelibs.fess.es.log.cbean.ClickLogCB;
47 import org.codelibs.fess.es.log.cbean.FavoriteLogCB;
48 import org.codelibs.fess.es.log.cbean.SearchLogCB;
49 import org.codelibs.fess.es.log.cbean.UserInfoCB;
50 import org.codelibs.fess.es.log.exbhv.ClickLogBhv;
51 import org.codelibs.fess.es.log.exbhv.FavoriteLogBhv;
52 import org.codelibs.fess.es.log.exbhv.SearchLogBhv;
53 import org.codelibs.fess.es.log.exbhv.UserInfoBhv;
54 import org.codelibs.fess.es.log.exentity.ClickLog;
55 import org.codelibs.fess.es.log.exentity.FavoriteLog;
56 import org.codelibs.fess.es.log.exentity.SearchLog;
57 import org.codelibs.fess.es.log.exentity.UserInfo;
58 import org.codelibs.fess.exception.FessSystemException;
59 import org.codelibs.fess.helper.SystemHelper;
60 import org.codelibs.fess.mylasta.direction.FessConfig;
61 import org.codelibs.fess.taglib.FessFunctions;
62 import org.dbflute.optional.OptionalEntity;
63
64 public class SearchLogService {
65
66 private static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
67
68 private static final String COUNT = "count";
69
70 private static final String KEY = "key";
71
72 private static final String ID = "id";
73
74 private static final String USER_INFO_ID = "userInfoId";
75
76 private static final String QUERY_TIME = "queryTime";
77
78 private static final Logger logger = LogManager.getLogger(SearchLogService.class);
79
80 @Resource
81 private SearchLogBhv searchLogBhv;
82
83 @Resource
84 private ClickLogBhv clickLogBhv;
85
86 @Resource
87 private FavoriteLogBhv favoriteLogBhv;
88
89 @Resource
90 private UserInfoBhv userInfoBhv;
91
92 @Resource
93 private SystemHelper systemHelper;
94
95 @Resource
96 protected FessConfig fessConfig;
97
98 public void deleteBefore(final int days) {
99 searchLogBhv.queryDelete(cb -> {
100 cb.query().setRequestedAt_LessEqual(systemHelper.getCurrentTimeAsLocalDateTime().minusDays(days));
101 });
102 }
103
104 public List<?> getSearchLogList(final SearchLogPager pager) {
105 final EsPagingResultBean<?> list;
106 if (SearchLogPager.LOG_TYPE_USERINFO.equalsIgnoreCase(pager.logType)) {
107 list = (EsPagingResultBean<?>) userInfoBhv.selectPage(cb -> {
108 cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
109 cb.query().addOrderBy_UpdatedAt_Desc();
110 createUserInfoCondition(pager, cb);
111 });
112 } else if (SearchLogPager.LOG_TYPE_CLICK.equalsIgnoreCase(pager.logType)) {
113 list = (EsPagingResultBean<?>) clickLogBhv.selectPage(cb -> {
114 cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
115 cb.query().addOrderBy_RequestedAt_Desc();
116 createClickLogCondition(pager, cb);
117 });
118 } else if (SearchLogPager.LOG_TYPE_CLICK_COUNT.equalsIgnoreCase(pager.logType)) {
119 list = (EsPagingResultBean<?>) clickLogBhv.selectPage(cb -> {
120 cb.fetchFirst(0);
121 createClickLogCondition(pager, cb);
122 cb.aggregation().setUrl_Terms(SearchLogPager.LOG_TYPE_CLICK_COUNT, op -> {
123 op.size(pager.getPageSize());
124 if (fessConfig.getSearchlogAggShardSizeAsInteger() >= 0) {
125 op.shardSize(fessConfig.getSearchlogAggShardSizeAsInteger());
126 }
127 }, null);
128 });
129 final Terms agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_CLICK_COUNT);
130 final List<? extends Terms.Bucket> buckets = agg.getBuckets();
131 updatePagerByAgg(pager, buckets.size());
132 return buckets.stream().map(e -> {
133 final Map<String, Object> map = new HashMap<>();
134 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
135 map.put(KEY, e.getKeyAsString());
136 map.put(COUNT, e.getDocCount());
137 return map;
138 }).collect(Collectors.toList());
139 } else if (SearchLogPager.LOG_TYPE_FAVORITE.equalsIgnoreCase(pager.logType)) {
140 list = (EsPagingResultBean<?>) favoriteLogBhv.selectPage(cb -> {
141 cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
142 cb.query().addOrderBy_CreatedAt_Desc();
143 createFavoriteLogCondition(pager, cb);
144 });
145 } else if (SearchLogPager.LOG_TYPE_FAVORITE_COUNT.equalsIgnoreCase(pager.logType)) {
146 list = (EsPagingResultBean<?>) favoriteLogBhv.selectPage(cb -> {
147 cb.fetchFirst(0);
148 createFavoriteLogCondition(pager, cb);
149 cb.aggregation().setUrl_Terms(SearchLogPager.LOG_TYPE_FAVORITE_COUNT, op -> {
150 op.size(pager.getPageSize());
151 if (fessConfig.getSearchlogAggShardSizeAsInteger() >= 0) {
152 op.shardSize(fessConfig.getSearchlogAggShardSizeAsInteger());
153 }
154 }, null);
155 });
156 final Terms agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_FAVORITE_COUNT);
157 final List<? extends Terms.Bucket> buckets = agg.getBuckets();
158 updatePagerByAgg(pager, buckets.size());
159 return buckets.stream().map(e -> {
160 final Map<String, Object> map = new HashMap<>();
161 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
162 map.put(KEY, e.getKeyAsString());
163 map.put(COUNT, e.getDocCount());
164 return map;
165 }).collect(Collectors.toList());
166 } else if (SearchLogPager.LOG_TYPE_SEARCH_COUNT_HOUR.equalsIgnoreCase(pager.logType)) {
167 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
168 cb.fetchFirst(0);
169 createSearchLogCondition(pager, cb);
170 cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_COUNT_HOUR, op -> {
171 op.calendarInterval(DateHistogramInterval.HOUR);
172 op.minDocCount(0);
173 op.order(BucketOrder.key(true));
174 }, null);
175 });
176 final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_COUNT_HOUR);
177 final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
178 updatePagerByAgg(pager, buckets.size());
179 return buckets.stream().map(e -> {
180 final Map<String, Object> map = new HashMap<>();
181 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
182 map.put(KEY, e.getKeyAsString());
183 map.put(COUNT, e.getDocCount());
184 return map;
185 }).collect(Collectors.toList());
186 } else if (SearchLogPager.LOG_TYPE_SEARCH_COUNT_DAY.equalsIgnoreCase(pager.logType)) {
187 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
188 cb.fetchFirst(0);
189 createSearchLogCondition(pager, cb);
190 cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_COUNT_DAY, op -> {
191 op.calendarInterval(DateHistogramInterval.DAY);
192 op.minDocCount(0);
193 op.order(BucketOrder.key(true));
194 }, null);
195 });
196 final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_COUNT_DAY);
197 final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
198 updatePagerByAgg(pager, buckets.size());
199 return buckets.stream().map(e -> {
200 final Map<String, Object> map = new HashMap<>();
201 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
202 map.put(KEY, e.getKeyAsString());
203 map.put(COUNT, e.getDocCount());
204 return map;
205 }).collect(Collectors.toList());
206 } else if (SearchLogPager.LOG_TYPE_SEARCH_USER_HOUR.equalsIgnoreCase(pager.logType)) {
207 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
208 cb.fetchFirst(0);
209 createSearchLogCondition(pager, cb);
210 cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_USER_HOUR, op -> {
211 op.calendarInterval(DateHistogramInterval.HOUR);
212 op.subAggregation(AggregationBuilders.cardinality(USER_INFO_ID).field(USER_INFO_ID));
213 op.minDocCount(0);
214 op.order(BucketOrder.key(true));
215 }, null);
216 });
217 final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_USER_HOUR);
218 final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
219 updatePagerByAgg(pager, buckets.size());
220 return buckets.stream().map(e -> {
221 final Map<String, Object> map = new HashMap<>();
222 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
223 map.put(KEY, e.getKeyAsString());
224 final Cardinality value = e.getAggregations().get(USER_INFO_ID);
225 map.put(COUNT, value.getValue());
226 return map;
227 }).collect(Collectors.toList());
228 } else if (SearchLogPager.LOG_TYPE_SEARCH_USER_DAY.equalsIgnoreCase(pager.logType)) {
229 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
230 cb.fetchFirst(0);
231 createSearchLogCondition(pager, cb);
232 cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_USER_DAY, op -> {
233 op.calendarInterval(DateHistogramInterval.DAY);
234 op.subAggregation(AggregationBuilders.cardinality(USER_INFO_ID).field(USER_INFO_ID));
235 op.minDocCount(0);
236 op.order(BucketOrder.key(true));
237 }, null);
238 });
239 final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_USER_DAY);
240 final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
241 updatePagerByAgg(pager, buckets.size());
242 return buckets.stream().map(e -> {
243 final Map<String, Object> map = new HashMap<>();
244 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
245 map.put(KEY, e.getKeyAsString());
246 final Cardinality value = e.getAggregations().get(USER_INFO_ID);
247 map.put(COUNT, value.getValue());
248 return map;
249 }).collect(Collectors.toList());
250 } else if (SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_HOUR.equalsIgnoreCase(pager.logType)) {
251 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
252 cb.fetchFirst(0);
253 createSearchLogCondition(pager, cb);
254 cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_HOUR, op -> {
255 op.calendarInterval(DateHistogramInterval.HOUR);
256 op.subAggregation(AggregationBuilders.avg(QUERY_TIME).field(QUERY_TIME));
257 op.minDocCount(0);
258 op.order(BucketOrder.key(true));
259 }, null);
260 });
261 final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_HOUR);
262 final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
263 updatePagerByAgg(pager, buckets.size());
264 return buckets.stream().map(e -> {
265 final Map<String, Object> map = new HashMap<>();
266 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
267 map.put(KEY, e.getKeyAsString());
268 final Avg value = e.getAggregations().get(QUERY_TIME);
269 map.put(COUNT, value.getValueAsString());
270 return map;
271 }).collect(Collectors.toList());
272 } else if (SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_DAY.equalsIgnoreCase(pager.logType)) {
273 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
274 cb.fetchFirst(0);
275 createSearchLogCondition(pager, cb);
276 cb.aggregation().setRequestedAt_DateHistogram(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_DAY, op -> {
277 op.calendarInterval(DateHistogramInterval.DAY);
278 op.subAggregation(AggregationBuilders.avg(QUERY_TIME).field(QUERY_TIME));
279 op.minDocCount(0);
280 op.order(BucketOrder.key(true));
281 }, null);
282 });
283 final Histogram agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_REQTIMEAVG_DAY);
284 final List<? extends Histogram.Bucket> buckets = agg.getBuckets();
285 updatePagerByAgg(pager, buckets.size());
286 return buckets.stream().map(e -> {
287 final Map<String, Object> map = new HashMap<>();
288 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
289 map.put(KEY, e.getKeyAsString());
290 final Avg value = e.getAggregations().get(QUERY_TIME);
291 map.put(COUNT, value.getValueAsString());
292 return map;
293 }).collect(Collectors.toList());
294 } else if (SearchLogPager.LOG_TYPE_SEARCH_KEYWORD.equalsIgnoreCase(pager.logType)) {
295 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
296 cb.fetchFirst(0);
297 createSearchLogCondition(pager, cb);
298 cb.aggregation().setSearchWord_Terms(SearchLogPager.LOG_TYPE_SEARCH_KEYWORD, op -> {
299 op.size(pager.getPageSize());
300 if (fessConfig.getSearchlogAggShardSizeAsInteger() >= 0) {
301 op.shardSize(fessConfig.getSearchlogAggShardSizeAsInteger());
302 }
303 }, null);
304 });
305 final Terms agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_KEYWORD);
306 final List<? extends Terms.Bucket> buckets = agg.getBuckets();
307 updatePagerByAgg(pager, buckets.size());
308 return buckets.stream().map(e -> {
309 final Map<String, Object> map = new HashMap<>();
310 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
311 map.put(KEY, e.getKeyAsString());
312 map.put(COUNT, e.getDocCount());
313 return map;
314 }).collect(Collectors.toList());
315 } else if (SearchLogPager.LOG_TYPE_SEARCH_ZEROHIT.equalsIgnoreCase(pager.logType)) {
316 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
317 cb.fetchFirst(0);
318 createSearchLogCondition(pager, cb);
319 cb.query().setHitCount_Equal(0L);
320 cb.aggregation().setSearchWord_Terms(SearchLogPager.LOG_TYPE_SEARCH_ZEROHIT, op -> {
321 op.size(pager.getPageSize());
322 if (fessConfig.getSearchlogAggShardSizeAsInteger() >= 0) {
323 op.shardSize(fessConfig.getSearchlogAggShardSizeAsInteger());
324 }
325 }, null);
326 });
327 final Terms agg = list.getAggregations().get(SearchLogPager.LOG_TYPE_SEARCH_ZEROHIT);
328 final List<? extends Terms.Bucket> buckets = agg.getBuckets();
329 updatePagerByAgg(pager, buckets.size());
330 return buckets.stream().map(e -> {
331 final Map<String, Object> map = new HashMap<>();
332 map.put(ID, Base64.getUrlEncoder().encodeToString(e.getKeyAsString().getBytes(StandardCharsets.UTF_8)));
333 map.put(KEY, e.getKeyAsString());
334 map.put(COUNT, e.getDocCount());
335 return map;
336 }).collect(Collectors.toList());
337
338
339
340
341
342
343 } else {
344 list = (EsPagingResultBean<?>) searchLogBhv.selectPage(cb -> {
345 cb.paging(pager.getPageSize(), pager.getCurrentPageNumber());
346 cb.query().addOrderBy_RequestedAt_Desc();
347 createSearchLogCondition(pager, cb);
348 });
349 }
350
351
352 BeanUtil.copyBeanToBean(list, pager, option -> option.include(Constants.PAGER_CONVERSION_RULE));
353 pager.setPageNumberList(list.pageRange(op -> {
354 op.rangeSize(fessConfig.getPagingPageRangeSizeAsInteger());
355 }).createPageNumberList());
356
357 return list;
358 }
359
360 private void updatePagerByAgg(final SearchLogPager pager, final int size) {
361 pager.setAllPageCount(1);
362 pager.setAllRecordCount(size);
363 pager.setCurrentPageNumber(1);
364 pager.setExistNextPage(false);
365 pager.setExistPrePage(false);
366 pager.setPageSize(pager.getPageSize());
367 }
368
369 private void createSearchLogCondition(final SearchLogPager pager, final SearchLogCB cb) {
370 if (StringUtil.isNotBlank(pager.queryId)) {
371 cb.query().setQueryId_Term(pager.queryId);
372 }
373 if (StringUtil.isNotBlank(pager.userSessionId)) {
374 cb.query().setUserSessionId_Term(pager.userSessionId);
375 }
376 if (StringUtil.isNotBlank(pager.accessType)) {
377 cb.query().setAccessType_Term(pager.accessType);
378 }
379 if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
380 final String[] values = pager.requestedTimeRange.split(" - ");
381 final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM);
382 try {
383 if (values.length > 0) {
384 cb.query().setRequestedAt_GreaterEqual(parseDateTime(values[0], formatter));
385 }
386 if (values.length > 1) {
387 cb.query().setRequestedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
388 }
389 } catch (final Exception e) {
390 if (logger.isDebugEnabled()) {
391 logger.debug("Failed to parse {}", pager.requestedTimeRange, e);
392 }
393 }
394 }
395 }
396
397 private void createFavoriteLogCondition(final SearchLogPager pager, final FavoriteLogCB cb) {
398 if (StringUtil.isNotBlank(pager.queryId)) {
399 cb.query().setQueryId_Term(pager.queryId);
400 }
401 if (StringUtil.isNotBlank(pager.userSessionId)) {
402 cb.query().setUserInfoId_Term(pager.userSessionId);
403 }
404 if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
405 final String[] values = pager.requestedTimeRange.split(" - ");
406 final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM);
407 try {
408 if (values.length > 0) {
409 cb.query().setCreatedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
410 }
411 if (values.length > 1) {
412 cb.query().setCreatedAt_LessEqual(parseDateTime(values[1], formatter));
413 }
414 } catch (final Exception e) {
415 if (logger.isDebugEnabled()) {
416 logger.debug("Failed to parse {}", pager.requestedTimeRange, e);
417 }
418 }
419 }
420 }
421
422 private void createUserInfoCondition(final SearchLogPager pager, final UserInfoCB cb) {
423 if (StringUtil.isNotBlank(pager.userSessionId)) {
424 cb.query().setId_Equal(pager.userSessionId);
425 }
426 if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
427 final String[] values = pager.requestedTimeRange.split(" - ");
428 final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM);
429 try {
430 if (values.length > 0) {
431 cb.query().setUpdatedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
432 }
433 if (values.length > 1) {
434 cb.query().setUpdatedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
435 }
436 } catch (final Exception e) {
437 if (logger.isDebugEnabled()) {
438 logger.debug("Failed to parse {}", pager.requestedTimeRange, e);
439 }
440 }
441 }
442 }
443
444 private void createClickLogCondition(final SearchLogPager pager, final ClickLogCB cb) {
445 if (StringUtil.isNotBlank(pager.queryId)) {
446 cb.query().setQueryId_Term(pager.queryId);
447 }
448 if (StringUtil.isNotBlank(pager.userSessionId)) {
449 cb.query().setUserSessionId_Term(pager.userSessionId);
450 }
451 if (StringUtil.isNotBlank(pager.requestedTimeRange)) {
452 final String[] values = pager.requestedTimeRange.split(" - ");
453 final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM);
454 try {
455 if (values.length > 0) {
456 cb.query().setRequestedAt_GreaterEqual(LocalDateTime.parse(values[0], formatter));
457 }
458 if (values.length > 1) {
459 cb.query().setRequestedAt_LessEqual(LocalDateTime.parse(values[1], formatter));
460 }
461 } catch (final Exception e) {
462 if (logger.isDebugEnabled()) {
463 logger.debug("Failed to parse {}", pager.requestedTimeRange, e);
464 }
465 }
466 }
467 }
468
469 protected LocalDateTime parseDateTime(final String value, final DateTimeFormatter formatter) {
470 return LocalDateTime.parse(value, formatter).atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
471 }
472
473 public OptionalEntity<?> getSearchLog(final String logType, final String id) {
474 if (SearchLogPager.LOG_TYPE_CLICK.equalsIgnoreCase(logType)) {
475 return clickLogBhv.selectByPK(id);
476 }
477 if (SearchLogPager.LOG_TYPE_FAVORITE.equalsIgnoreCase(logType)) {
478 return favoriteLogBhv.selectByPK(id);
479 }
480 if (SearchLogPager.LOG_TYPE_USERINFO.equalsIgnoreCase(logType)) {
481 return userInfoBhv.selectByPK(id);
482 } else {
483 return searchLogBhv.selectByPK(id);
484 }
485 }
486
487 public Map<String, String> getSearchLogMap(final String logType, final String id) {
488 if (SearchLogPager.LOG_TYPE_USERINFO.equalsIgnoreCase(logType)) {
489 return userInfoBhv.selectByPK(id).map(e -> {
490 final Map<String, String> params = new LinkedHashMap<>();
491 params.put("User Info ID", e.getId());
492 params.put("Created Time", FessFunctions.formatDate(e.getCreatedAt()));
493 params.put("Updated Time", FessFunctions.formatDate(e.getUpdatedAt()));
494 return params;
495 }).get();
496 }
497 if (SearchLogPager.LOG_TYPE_CLICK.equalsIgnoreCase(logType)) {
498 return clickLogBhv.selectByPK(id).map(e -> {
499 final Map<String, String> params = new LinkedHashMap<>();
500 params.put("ID", e.getId());
501 params.put("Query ID", e.getQueryId());
502 params.put("Doc ID", e.getDocId());
503 params.put("User Session ID", e.getUserSessionId());
504 params.put("URL", e.getUrl());
505 params.put("URL ID", e.getUrlId());
506 params.put("Order", toNumberString(e.getOrder()));
507 params.put("Query Requested Time", FessFunctions.formatDate(e.getQueryRequestedAt()));
508 params.put("Requested Time", FessFunctions.formatDate(e.getRequestedAt()));
509 return params;
510 }).get();
511 }
512 if (SearchLogPager.LOG_TYPE_FAVORITE.equalsIgnoreCase(logType)) {
513 return favoriteLogBhv.selectByPK(id).map(e -> {
514 final Map<String, String> params = new LinkedHashMap<>();
515 params.put("ID", e.getId());
516 params.put("Query ID", e.getQueryId());
517 params.put("Doc ID", e.getDocId());
518 params.put("User Info ID", e.getUserInfoId());
519 params.put("URL", e.getUrl());
520 params.put("Created Time", FessFunctions.formatDate(e.getCreatedAt()));
521 params.put("Requested Time", FessFunctions.formatDate(e.getRequestedAt()));
522 return params;
523 }).get();
524 } else {
525 return searchLogBhv.selectByPK(id).map(e -> {
526 final Map<String, String> params = new LinkedHashMap<>();
527 params.put("ID", e.getId());
528 params.put("Query ID", e.getQueryId());
529 params.put("User Info ID", e.getUserInfoId());
530 params.put("User Session ID", e.getUserSessionId());
531 params.put("Access Type", e.getAccessType());
532 params.put("Search Word", e.getSearchWord());
533 params.put("Requested Time", FessFunctions.formatDate(e.getRequestedAt()));
534 params.put("Query Time", toNumberString(e.getQueryTime()));
535 params.put("Response Time", toNumberString(e.getResponseTime()));
536 params.put("Hit Count", toNumberString(e.getHitCount()));
537 params.put("Offset", toNumberString(e.getQueryOffset()));
538 params.put("Page Size", toNumberString(e.getQueryPageSize()));
539 params.put("Client IP", e.getClientIp());
540 params.put("Referer", e.getReferer());
541 params.put("Languages", e.getLanguages());
542 params.put("Virtual Host", e.getVirtualHost());
543 params.put("Roles", e.getRoles() != null ? String.join(" ", e.getRoles()) : StringUtil.EMPTY);
544 params.put("User Agent", e.getUserAgent());
545 e.getSearchFieldLogList().stream().forEach(p -> {
546 params.put(p.getFirst(), p.getSecond());
547 });
548 return params;
549 }).get();
550 }
551 }
552
553 private String toNumberString(final Number value) {
554 return value != null ? value.toString() : StringUtil.EMPTY;
555 }
556
557 public void deleteSearchLog(final Object e) {
558 if (e instanceof ClickLog) {
559 clickLogBhv.delete((ClickLog) e);
560 } else if (e instanceof FavoriteLog) {
561 favoriteLogBhv.delete((FavoriteLog) e);
562 } else if (e instanceof UserInfo) {
563 userInfoBhv.delete((UserInfo) e);
564 } else if (e instanceof SearchLog) {
565 searchLogBhv.delete((SearchLog) e);
566 } else {
567 throw new FessSystemException("Unknown log entity: " + e);
568 }
569 }
570 }