Elasticsearch Log 관리 프로그램 - Java (1)

초이·2024년 4월 12일
0

Elasticsearch Log 관리 프로그램 - Java

이번 글에서는 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;
}
profile
MacBook이 갖고싶은 살암

0개의 댓글