ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바로 엘라스틱서치(Elasticsearch) 데이터 보내기 (단건,다건) Java to ELk
    APi 2024. 1. 14. 20:33
    반응형

    웹서비스중인 사이트의 로그를 ELK(Elasticsearch Kibana)로 보기 위해

    1건 전송과 한번에 여러건을 전송하는 일이 생겼다. // java rest APi

    삽질의 결과를 토대로 포스팅을 한다.

    ELK 기 본적으로 헤더에 Basic 인증정보를 넣어 API통신을 해야한다.  // "아이디:비밀번호" BASE64 인코딩을 해서 보냄.

    1. 단건 (1건) 보내기

    - _doc api 이용

    - method : POST

    - API주소 : https://엘라스틱서치주소/인덱스명/_doc

    - Java RestTemplate 클래스 사용

    - 전송 형식 (Body)

    { 
        "field1" : "value1" 
        , "field2" : "value2"
        , "field3" : "value3"
    }

    일반적인 json 형태로 보내면된다. 

    api주소의 중간 경로에는 반드시 인덱스명이 필요하다.

     

    전체소스

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setBasicAuth("엘라스틱서치 로그안 이이디", "엘라스틱서치 로그안 비밀번호");
    RestTemplate restTemplate = new RestTemplate();
    ElasticSearchReqVo reqVo = new ElasticSearchReqVo(); //보낼데이터가 이미 set됐다고 가정
    // HTTP POST 요청 및 응답 처리
    ResponseEntity<String> result = restTemplate.exchange(
        "API주소"
        , HttpMethod.POST
        , new HttpEntity<>(reqVo, headers)
        , String.class
    );

     

     

    2. 다건 (멀티) 보내기

    - _bulk api 이용

    - method : POST

    - API주소 : https://엘라스틱서치주소/_bulk

    - Java RestTemplate 클래스 사용

    - 만약 3건을 한번에 보낼 때 전송 형식 (body)

    {"index": {"_index": 인덱스명} }
    {  "field1" : "value1" ,  "field2" : "value2" ,  "field3" : "value3"}
    {"index": {"_index": 인덱스명} }
    {  "field1" : "value1" ,  "field2" : "value2" ,  "field3" : "value3"}
    {"index": {"_index": 인덱스명} }
    {  "field1" : "value1" ,  "field2" : "value2" ,  "field3" : "value3"}

    전송규격을 보면 배열의 형태도 아니고 콤마 구분자도 없고 이상한 형태다. 

    이것 때문에 삽질을 많이했다. 이런식으로 데이터를 보내본적이 없기 때문 ㅋ;

    body안에 인덱스명이 있어야한다. 인덱스영역의 중괄호, 데이터영역의 중괄호 이 2중괄호가 1개의 데이터를 전송한다.

    마지막엔 꼭 \n을 2번 해야한다.

    전체소스

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setBasicAuth("엘라스틱서치 로그안 이이디", "엘라스틱서치 로그안 비밀번호");
    RestTemplate restTemplate = new RestTemplate();
    ElasticSearchReqVo reqVo = new ElasticSearchReqVo(); //보낼데이터가 이미 set됐다고 가정
    StringBuilder bulkRequestBody = new StringBuilder();
    ObjectMapper objectMapper = new ObjectMapper();
    
    //bulk 형태로 보내는 전송규격으로 변경한다.
    bulkRequestBody.append("{ \"index\" : { \"_index\" : \"" + "인덱스명" + "\" } }\n");
    bulkRequestBody.append(objectMapper.writeValueAsString(reqVo)).append("\n\n");
    
    ResponseEntity<String> result = restTemplate.exchange(
        "API주소"
        , HttpMethod.POST
        , new HttpEntity<>(bulkRequestBody.toString(), headers)
        , String.class
    );

     

    반응형

    댓글

Designed by Tistory.