APi

자바로 엘라스틱서치(Elasticsearch) 데이터 보내기 (단건,다건) Java to ELk

dev.mk 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
);

 

반응형