본문 바로가기

Framework/Spring

[Spring] docker, Elasticsearch, SpringBoot로 검색 기능 구현 - 컴도리돌이

728x90

 

 

[Docker] 도커로 ELK8버전 사용하기 - 컴도리돌이

이번에 회사에서 ELK를 도입을 본격적으로 시작하였습니다. 🥺 하지만 올해 초부터 책도 선물 받고 잠깐 열심히 공부했지만, 역시 저란 인간은,, 나태 그 자체였습니다. 그래서 뭐 좀 알고 사용

comdolidol-i.tistory.com


 

저번 포스팅에서 도커(dcoker)를 통해 ELK를 실행시켰습니다. 이번에는 스프링부트에서 Elasticsearch로 간단한 검색 API를 구현하려고 해요. 

먼저 Spring Boot에서 Elasticsearch와 통신하기 위해 필요한 의존성을 추가해야 합니다. spring-data-elasticsearch 라이브러리를 사용하여 Elasticesearch와 연동할 수 있어요 😊

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
    implementation 'org.elasticsearch.client:elasticsearch-rest-client:8.10.0'
    ...
}

 

위에 의존성을 추가했으면, Spring BootElasticsearch 클러스터와 연결할 수 있도록 application.yml 파일에 설정을 추가해야 해요.

spring:
  elasticsearch:
    uris: localhost:9200
    username: elastic
    password: changeme
    
    ...

 

위에 설정은 Docker에서 실행 중인 Elasticsearch에 연결하도록 구성됩니다. 저는 Docker의. env 파일에서 아이디를 elastic, 비밀번호는 changeme로 설정하였기 때문에, 위와 같이 설정하면 되었습니다. 

이제 Elasticesearch와 통신할 수 있도록 ElasticsearchConfig를 생성하여 설정해 줄 거예요.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration;

@Configuration
public class ElasticsearchConfig extends ElasticsearchConfiguration {

    @Value("${spring.elasticsearch.username}")
    private String username;

    @Value("${spring.elasticsearch.password}")
    private String password;

    @Value("${spring.elasticsearch.uris}")
    private String host;

    @Override
    public ClientConfiguration clientConfiguration() {
        return ClientConfiguration.builder()
                .connectedTo(host)
                .withBasicAuth(username, password)
                .build();
    }
}

 

Spring BootElasticsearch 간의 통신을 설정하기 위해, ElasticsearchConfig 클래스를 생성했습니다. 이 클래스는 ElasticsearchConfiguration을 상속받아 Spring Boot에서 Elasticsearch 클러스터에 쉽게 연결할 수 있도록 합니다.

우선, ElasticsearchConfiguration을 상속한 이유는 Spring Boot가 제공하는 기본 Elasticsearch 클라이언트 설정을 커스터마이징 하기 위함입니다. SpringElasticsearch와의 통신을 간편하게 처리할 수 있는 내장 클래스를 제공하는데, 이를 확장해 맞춤형 설정을 추가할 수 있습니다. 여기서 핵심 설정은 clientConfiguration() 메서드입니다. 이 메서드는 Elasticsearch 클러스터와의 연결을 정의해요. connectedTo(host)application.yml 파일에 정의한 호스트 주소(Elasticsearch 서버)를 사용해 연결을 설정하고, withBasicAuth(username, password)는 기본 인증을 추가하여 보안을 유지합니다. 즉, 클러스터에 연결할 때 필요한 인증 정보를 함께 제공하는 것입니다.

 

Elasticsearch Clients :: Spring Data Elasticsearch

Client behaviour can be changed via the ClientConfiguration that allows to set options for SSL, connect and socket timeouts, headers and other parameters. Example 1. Client Configuration import org.springframework.data.elasticsearch.client.ClientConfigurat

docs.spring.io


Entity

먼저, Log 엔티티는 Elasticsearch에 저장될 문서 구조를 정의합니다. @Document 어노테이션을 사용해 Elasticsearch 인덱스(logstash-*)와 연동되며, @Id는 문서의 고유 식별자 역할을 합니다. 이 엔티티는 Elasticsearch에서 데이터를 주고받는 구조로 message, timestamp 등의 필드를 포함합니다.

import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Getter
@Setter
@Document(indexName = "logstash-*")
public class Log {
    @Id
    private String id;
    private String message;
    private String timestamp;
}

Repository

LogRepositoryElasticsearchRepository를 상속받아, Elasticsearch와의 기본 CRUD 기능을 제공합니다. 이 리포지토리는 Log 엔티티와 연결되어 있으며, String 타입의 ID를 사용해 데이터를 관리합니다. Spring Data JPA와 유사한 방식으로 Elasticsearch의 데이터를 조회, 저장할 수 있습니다.

import org.homepage.parksangji.entity.Log;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface LogRepository extends ElasticsearchRepository<Log, String> {
}

Service

LogService는 비즈니스 로직을 처리하는 레이어입니다. LogRepository를 주입받아, Elasticsearch에서 로그 데이터를 조회하는 역할을 합니다. 여기서는 findAllLogs() 메서드를 통해 모든 로그 데이터를 조회하고 반환하는 기능을 제공합니다. 이 서비스는 컨트롤러와 리포지토리 사이에서 데이터를 처리하는 중간 역할을 합니다.

import org.homepage.parksangji.entity.Log;
import org.homepage.parksangji.repository.LogRepository;
import org.springframework.stereotype.Service;

@Service
public class LogService {

    private final LogRepository logRepository;

    public LogService(LogRepository logRepository) {
        this.logRepository = logRepository;
    }

    public Iterable<Log> findAllLogs() {
        return logRepository.findAll();
    }
}

Controller

LogController는 API 엔드포인트를 제공하는 레이어이에요.  /logs/getAll 경로로 GET 요청을 받으면, LogService findAllLogs() 메서드를 호출하여 모든 로그 데이터를 조회하고, 이를 API 응답으로 반환합니다. 이 컨트롤러를 통해 클라이언트가 Elasticsearch의 데이터를 API로 조회할 수 있습니다.

import org.homepage.parksangji.entity.Log;
import org.homepage.parksangji.service.LogService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/logs")
public class LogController {

    private final LogService logService;

    public LogController(LogService logService) {
        this.logService = logService;
    }

    @GetMapping("/getAll")
    public Iterable<Log> getAllLogs() {
        return logService.findAllLogs();
    }
}

 


다음 포스팅에서는 실제 데이터를 Elasticsearch에 추가하거나 삭제하는 방법을 알아보고, 더 세부적인 쿼리 방식과 최적화 방법에 대해 다뤄보려고 합니다. 앞으로 더욱 깊이 있는 Elasticsearch의 활용 방법을 탐구해 보겠습니다. 😚😚