Obsidian/Recognition/Programing/ELK/Elastic Search + Spring Boo...

6.3 KiB

  • Kibana Test 쿼리

POST replay_log_*/_search
{
  "size" : 10000,
  "track_total_hits": true,
  "query" : {
    "bool" : {
      "filter" : [
        {
          "terms" : {
            "header.msg_type.keyword" : [
              10
            ]
          }
        },
        {
          "range" : {
            "header.recv_time" : {
              "from" : "20240416090000.000",
              "to" : "20240416103059.999"
            }
          }
        }
      ]
    }
  },
  "_source": ["@timestamp", "header", "message"],
  "sort" : [{"header.recv_time.keyword" : {"order" : "ASC"}}],
  "search_after" : ["0"]
}

  • Elasticsearch 라이브러리 사용

public String elkSearch_replay_log(String sLogIndex, String sStartDt, String sEndDt) {

        // String sLogType = "3"; // 재생용 로그 S/W구분
        // String sStart_tm = "20240219160000.000"; // 일시(from)
        // String sEnd_tm = "20240219170000.000";   // 일시(to)

        List<Object> sAfter = null;   // 일시(to)

        List<IndexReplayMsg> productMatches = new ArrayList<IndexReplayMsg>();
        
        String esQuery =    "{                                                   " + //
                            "    \"bool\" : {                                    " + //
                            "      \"filter\" : [                                " + //
                            "        { \"terms\" : {                             " + //
                            "            \"header.msg_type.keyword\" : [         " + //
                            "              "+ sLogIndex +"             ] } },    " + //
                            "        { \"range\" : {                             " + //
                            "            \"header.recv_time\" : {                " + //
                            "              \"from\" : \""+ sStartDt +"\",        " + //
                            "                \"to\" : \""+ sEndDt +"\" } } } ] } " + //
                            "}";
                        
        Query searchQuery = new StringQuery(esQuery);

        // 한번에 가져올 row수 설정
        ((BaseQuery) searchQuery).setMaxResults(1000);

        // 페이징( PageRequest.of( 페이지번호( 총개수 / size ), size) )
        //searchQuery.setPageable(PageRequest.of(62, 10)); // 620번째 로우부터 10개까지 가져옴

        // 데이터 정렬할 필드 설정 
        searchQuery.addSort(Sort.by(new Sort.Order(Sort.Direction.ASC, "header.recv_time.keyword")));

        LocalDateTime dt_before = LocalDateTime.now();

        while (true) {

            searchQuery.setSearchAfter(sAfter);

            // 검색 요청하여 검색 결과 가져오기
            SearchHits<IndexReplayMsg> productHits = elasticsearchOperations.search(searchQuery, IndexReplayMsg.class, IndexCoordinates.of("replay_log_*"));

            if (productHits.getTotalHits() <= 0) break;
            
            Duration diff = Duration.between(dt_before, LocalDateTime.now());
            
            logger.info("elastic Call " + productHits.getTotalHits() + "건 " + diff.toMillis() + "msec");

            sAfter = productHits.toList().get(productHits.toList().size() -1).getSortValues();

            // IndexFusion Object에 데이터 담기
            productHits.forEach(srcHit -> {
                productMatches.add(srcHit.getContent());
            });

            
            logger.info("map cnt " + productMatches.size() + "건 " );

            if (productHits.toList().size() != 1000) {
                break;
            }

        }
        

        return "OK";
    }

  • Post요청 -> 결과 Map 반환

public String searchReplayDSL(String sIndex, String sStartDt, String sEndDt) {


        while (true) {

            String sQeury = "{\r\n" + //
                                "  \"size\" : 10000,\r\n" + //
                                "  \"track_total_hits\": true,\r\n" + //
                                "  \"query\" : {\r\n" + //
                                "    \"bool\" : {\r\n" + //
                                "      \"filter\" : [\r\n" + //
                                "        {\r\n" + //
                                "          \"terms\" : {\r\n" + //
                                "            \"header.msg_type.keyword\" : [\r\n" + //
                                "              10\r\n" + //
                                "            ]\r\n" + //
                                "          }\r\n" + //
                                "        },\r\n" + //
                                "        {\r\n" + //
                                "          \"range\" : {\r\n" + //
                                "            \"header.recv_time\" : {\r\n" + //
                                "              \"from\" : \"20240416090000.000\",\r\n" + //
                                "              \"to\" : \"20240416103059.999\"\r\n" + //
                                "            }\r\n" + //
                                "          }\r\n" + //
                                "        }\r\n" + //
                                "      ]\r\n" + //
                                "    }\r\n" + //
                                "  },\r\n" + //
                                "  \"_source\": [\"@timestamp\", \"header\", \"message\"],\r\n" + //
                                "  \"sort\" : [{\"header.recv_time.keyword\" : {\"order\" : \"ASC\"}}],\r\n" + //
                                "  \"search_after\" : [\"0\"]\r\n" + //
                                "}";

                        // MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
                        // params.add("Content-Type", "application/json");

                        HttpHeaders headers = new HttpHeaders();
                        headers.add("Content-Type", "application/json");

                        HttpEntity<String> entity = new HttpEntity<String>(sQeury, headers);


                        RestTemplate rt = new RestTemplate(); 

                        Map<String, Object> personResultAsJsonStr = rt.postForObject("http://10.200.31.130:9200/replay_log_*/_search", entity, Map.class);
                        
            if (personResultAsJsonStr != null) {
                break;
            }       

        }
        

        return "OK";
    }