이번 글에서는 Java로 작성한 Elasticsearch 로그 관리 프로그램에 대해 설명할 것 이다. 이 프로그램은 여러 기능을 제공하여 Elasticsearch 로그 데이터를 효율적으로 관리하고 검색할 수 있다. 아래에 프로그램의 주요 기능과 코드를 분석해보자.
1. 로그 검색 및 페이징:
검색 조건에 맞는 로그 데이터를 Elasticsearch에서 검색하고, 페이징 처리하여 결과를 반환할 수 있다.
2. 문서 생성:
주어진 로그 데이터를 Elasticsearch에 문서로 생성할 수 있다.
3. 인덱스 설정 업데이트:
특정 인덱스의 설정을 업데이트할 수 있다.
4. 인덱스 삭제:
주어진 인덱스를 삭제할 수 있다.
5. 모든 인덱스 목록 가져오기:
Elasticsearch에 존재하는 모든 인덱스의 목록을 가져올 수 있다.
1. 로그 검색 및 페이징
getSearchLogList 메서드는 주어진 검색 조건에 맞는 로그 데이터를 검색하고 페이징 처리하여 반환하는 기능을 수행한다. BoolQueryBuilder를 사용하여 복잡한 검색 쿼리를 구성하고, SearchSourceBuilder를 사용하여 검색 요청을 작성한다.
public PageDto<LogsDto> getSearchLogList(SearchLogDto searchLogDto) throws IOException {
PageDto<LogsDto> dto = new PageDto<>();
BoolQueryBuilder boolQueryBuilder = queryBuilder(searchLogDto);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.sort(Str_time, SortOrder.DESC);
searchSourceBuilder.from((searchLogDto.getPageNum() - 1) * searchLogDto.getRowCnt());
searchSourceBuilder.size(searchLogDto.getRowCnt());
searchSourceBuilder.trackTotalHits(true);
ArrayList<String> eqIdList = new ArrayList<>();
for (Long eqId : searchLogDto.getEqId()) {
eqIdList.add(eqId.toString() + "-*");
}
SearchRequest searchRequest = new SearchRequest();
String[] indices = eqIdList.stream().map(Object::toString).toArray(String[]::new);
searchRequest.indices(indices);
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = searchResponse.getHits();
long totalCount = searchHits.getTotalHits().value;
indexMaxResult(eqIdList, totalCount);
List<LogsDto> logsDtoList = Arrays.stream(searchHits.getHits())
.map(this::mapToLogsDto)
.collect(Collectors.toList());
dto.setContent(logsDtoList);
dto.setTotalPages((int) Math.ceil((double) totalCount / searchLogDto.getRowCnt()));
dto.setTotalElements(totalCount);
dto.setFirst(searchLogDto.getPageNum() == 1);
dto.setLast(searchLogDto.getPageNum() == dto.getTotalPages());
} catch (IOException e) {
logger.error("Error occurred while searching documents: {}", e.getMessage());
return new PageDto<>();
}
return dto;
}
queryBuilder 메서드는 주어진 검색 조건을 기반으로 BoolQueryBuilder를 생성한다. 이를 통해 다양한 필드에 대한 조건을 유연하게 추가할 수 있다.
private BoolQueryBuilder queryBuilder(SearchLogDto searchLogDto) {
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
if (searchLogDto.getMessage() != null)
boolQueryBuilder.must(QueryBuilders.matchQuery(Str_message, searchLogDto.getMessage()).analyzer("camel_analyzer").operator(Operator.AND));
if (searchLogDto.getWatch() != null)
boolQueryBuilder.must(QueryBuilders.matchQuery(Str_watch, searchLogDto.getWatch()).analyzer("camel_analyzer").operator(Operator.AND));
if (searchLogDto.getNodeId() != null)
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery(Str_nodeId, searchLogDto.getNodeId()));
boolQueryBuilder.must(QueryBuilders.matchQuery(Str_level, String.join(",", searchLogDto.getLevel())));
if (searchLogDto.getStartTime() != null && searchLogDto.getEndTime() != null) {
searchLogDto.setStartTime(setTime(searchLogDto.getStartTime()));
searchLogDto.setEndTime(setTime(searchLogDto.getEndTime()));
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(Str_time)
.gte(searchLogDto.getStartTime())
.lt(searchLogDto.getEndTime());
boolQueryBuilder.must(rangeQuery);
}
return boolQueryBuilder;
}
mapToLogsDto 메서드는 Elasticsearch의 검색 결과를 LogsDto 객체로 매핑한다. 검색된 각 문서의 소스 데이터를 LogsDto로 변환하고, 문서 ID를 설정한다.
private LogsDto mapToLogsDto(SearchHit hit) {
String sourceAsString = hit.getSourceAsString();
String id = hit.getId(); // Document ID 추출
if (sourceAsString != null) {
try {
ObjectMapper objectMapper = new ObjectMapper();
LogsDto logsDto = objectMapper.readValue(sourceAsString, LogsDto.class);
logsDto.setId(id); // Document ID 설정
return logsDto;
} catch (JsonProcessingException e) {
logger.error("Error while mapping JSON to LogsDto: {}", e.getMessage());
return null;
}
}
return null;
}