티스토리 뷰

Elastic Stack

  • ELK: Elasticsearch, Logstash, Kibana
    • Elasticsearch: 검색 및 분석엔진
    • Logstash: 서버 사이드 데이터 처리 파이프라인, 여러 소스의 데이터를 수집하여 변환한 뒤 elasticsearch 에 전송
    • Kibana: Elasticsearch 의 내용을 차트와 그래프를 이용해 데이터를 시각화
  • Beats: 경량의 단일 목적 데이터 수집기 제품군
  • Elastic Stack: EKL + Beat

우리 서비스 ELK Stack 구성

ELK 모식도

  • ElasticSeach, Logstash, Kibana는 docker-elk 레포지토리를 참고하여 설정
  • 각각의 GM 서버에는 로그 정보를 Logstash에 전달하는 filebeat를 설치

FileBeat

  • 로그가 있는 서버에 설치
  • Beats 의 제품군에는 여러가지가 존재하는데 그 중 로그파일 전용이 Filebeat
filebeat.inputs:
- type: log
  # 도커 컨터이너로부터 쌓이는 로그의 경로 설정
  paths:
    - '/var/lib/docker/containers/*/*.log'
  # docker 의 로그는 json 형태로 쌓이는데 json.message_key 는 해당 key 에 해당하는 정보를 위로 올려준다.
  json.keys_under_root: true
  json.overwrite_keys: true
  json.add_error_key: true
  json.expand_keys: true
  json.message_key: log
  # 로그를 한줄한줄이 아닌 원하는 패턴의 단위로 묶어서 보내줄 수 있다.
  multiline.type: pattern
  multiline.pattern: '^Epoch'
  multiline.negate: true
  multiline.match: after
  # default 는 5초로 셋팅되어 있다. 묶어주는 로그 단위가 크면 중간에 의도한대로 나오지 않고 짤렸기 때문에 늘려주었다.
  multiline.timeout: 30
output.logstash:
  hosts: [${로그스태시의 호스트 IP:PORT}]

Logstash 설정

  • filebeat 에서 로그를 받아 filter 로 분석하기
input {
        beats {
                port => Logstash에서 열어준 포트번호(default:5044)
        }
}

filter {
        # backspace 제거: 정형화된 로그가 아니다 보니 \b 부분이 문제가 되었는데 없애줌
        mutate {
                gsub => ["log","[\b]", ""]
        }
        # grok 을 사용하여 원하는 방식대로 로그를 filter
        # grok 문법을 사용하며, log 필드에 들어온 값을 정규표현식과 비슷하게 파싱하여 json 형태로 보내준다.
        # %{해당패턴:필드로_묶을_이름:자료형} -> 필드로 묶을 이름을 지정하지 않으면 해당패턴 명으로 묶인다.
        grok {
                match => {"log" => ["Epoch %{NUMBER:currentEpoch:int}\/%{NUMBER:totalEpoch:int}
  %{GREEDYDATA}- loss: %{NUMBER:loss:float} - accuracy: %{NUMBER:accuracy:float}"] }
        }
        # jobId를 태그로 관리: [] 방식으로 json 경로의 key 접근가능
        mutate {
                rename => {"[attrs][tag]" => "jobId"}
        }
}

output {
        elasticsearch {
                hosts => 엘라스틱 포트
                # .. 각종 설정정보 넣어줌 ..
                # index 는 job 으로 클러스터링
                index => "job"
        }
}

Kibana

  • kibana 는 elastic 에서 API 를 통해 봐야하는 로그정보들을 쉽게 시각화 해줌 (개발하며 로그 시각화 및 모니터링이 가능)
  • 우리 서비스에서 kibana 를 사용하여 로그를 시각화 하지는 않았고, 프론트엔드 팀원들이 시각화를 진행

ElasticSearch

  • SpringBoot 를 사용한다면 의존성 추가로 쉽게 적용이 가능하다.
  • gradle 설정에서 implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'를 추가
  • Java 에서 Repository 처럼 쉽게 사용이 가능하다.
  • Config 설정을 해준다.
@Configuration
public class ElasticClientConfig extends AbstractElasticsearchConfiguration {
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {

        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(host)
                .withBasicAuth(userName, password)
                .build();

        return RestClients.create(clientConfiguration).rest();
    }
}
  • ElasticsearchRepository 를 상속받아 Repository 처럼 사용가능하다.
public interface LogRepository extends ElasticsearchRepository<Log, String> {
    List<Log> findByJobIdOrderByTime(Long jobId);
}

docker-compose.yml 설정

elk docker 설치 참고 레포짓토리의 설정 파일을 우리 환경에 맞게 수정을 진행했다.

version: '3.2'

services:
  elasticsearch:
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data
    ports:
      # EC2 인바운드 규칙으로 9000번 포트로 수정
      - "9000:9200"
      - "9300:9300"
    environment:
      # OOM 에러를 해결하기 위해 메모리 크기 수정
      ES_JAVA_OPTS: "-Xmx1g -Xms1g"
      ELASTIC_PASSWORD: password
      discovery.type: single-node
    networks:
      - elk

  logstash:
    build:
      context: logstash/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./logstash/config/logstash.yml
        target: /usr/share/logstash/config/logstash.yml
        read_only: true
      - type: bind
        source: ./logstash/pipeline
        target: /usr/share/logstash/pipeline
        read_only: true
    ports:
      # EC2 인바운드 규칙으로 8000번 포트로 수정
      - "8000:5044"
      - "5000:5000/tcp"
      - "5000:5000/udp"
      - "9600:9600"
    environment:
      # OOM 에러를 해결하기 위해 메모리 크기 수정
      LS_JAVA_OPTS: "-Xmx1g -Xms1g"
    networks:
      - elk
    depends_on:
      - elasticsearch

  kibana:
    build:
      context: kibana/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./kibana/config/kibana.yml
        target: /usr/share/kibana/config/kibana.yml
        read_only: true
    ports:
      # EC2 인바운드 규칙으로 8080번 포트로 수정
      - "8080:5601"
    networks:
      - elk
    depends_on:
      - elasticsearch

networks:
  elk:
    driver: bridge

volumes:
  elasticsearch:

참고

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함