ELK 를 이용한 로그 시각화 하기

ELK 를 이용한 로그 시각화 하기

2021, Sep 25    

로그를 처음 시각화해보면서 작성한 글이다.

로깅을 통해 개발자는 개발 과정 혹은 개발 후에 발생할 수 있는 예상치 못한 애플리케이션의 문제를 진달할 수 있고, 다양한 정보를 수집할 수 있다. 이렇듯 중요한 로깅을 어떤 로깅 수집 기술을 통해 확인하면 좋을지 생각해보자

ELK?

분석 및 저장 기능을 담당하는 ElasticSearch, 수집 기능을 하는 Logstash, 이를 시각화하는 도구인 Kibana 의 앞글자를 딴 단어다. 접근성과 용이성이 좋아 최근에 많이 사용되는 Log 및 데이터 분석 도구다.

Elasticsearch (로그 저장 및 검색)

텍스트, 숫자, 위치 기반 정보, 정형 및 비정형 데이터 등 모든 유형의 데이터를 위한 무료 검색 및 분석 엔진이다. 분산형과 개방형을 특징으로 한다. Elastic Stack 의 핵심 구성 요소다. Elasticsearch 로 흘러들어온 원시 데이터를 서로 관련있는 문서끼리 색인하여 복잡한 쿼리에 대해 요약 검색을 할 수 있도록 제공한다. 관계형 데이터베이스가 document 중심이라면 Elasticsearch 는 텍스트 중심이라고 볼 수 있다. 관계형 데이터베이스를 베이스로 검색에 필요한 부분을 Elasticsearch 로 진행하는 것이 보통이다.

Logstash (로그 수집 엔진)

실시간 파이프라인 기능을 가진 오픈소스 데이터 수집 엔진이다. 서로 다른 소스의 데이터를 탄력적으로 통합하고 사용자가 선택한 목적지로 데이터를 정규화할 수 있다. 수평 확장이 가능한 데이터 처리 파이프라인을 다양한 입력, 필터, 출력을 믹스매치하고 조정하면서 파이프라인에서 조화롭게 운용 가능하다.

Kibana (로그 시각화 및 관리)

ElasticSearch 에서 색인된 데이터를 검색하고 시각화 하는 기능을 제공하는 Elastic Stack 을 기반으로 구축된 프론트엔드 애플리케이션이다.

Filebeat

로그 데이터를 전달하고 중앙화하기 위한 경량의 Producer 다. 서버에 에이전트로 설치되며, 지정한 로그 파일 또는 위치를 모니터링하고 로그 이벤트를 수집한 다음 인덱싱을 위해 Elasticsearch 또는 Logstash 로 전달한다.

장점

  • Elastic 회사에서 제공하는 오픈 소스다.
  • ELK 자체로는 무료로 사용가능하다.
  • 오픈소스를 설치하는 것만으로 구축이 완료된다.
  • 추가적인 개발 과정없고, 사용이 쉬워 접근성이 뛰어나다.
  • 실시간에 가깝게 데이터를 처리할 수 있다.
  • E, L, K 에 해당하는 세 가지 모듈을 각각 해당하는 기능만 담당할 수 있다면 얼마든지 모듈교체가 가능하다.

ELK 가 어떤 것이고 어떤 방식으로 일련의 과정이 처리되는지 간단하게 살펴봤다.

ELK 적용

실습에 사용된 PC 환경은 MacOS 이며 Java 14 가 설치되어 있는(Java >= 8) 환경에서 작업을 시작한다. ELK 는 JVM 환경에서 돌아가니 반드시 Java 가 필요하며 Java 8 버전을 사용해야한다. Logstash 는 Java 9 이상은 지원되지 않는다.

  1. Java 를 설치 및 적용한다.

    현재 적용된 자바 버전을 확인한다.

    $ java -version
    openjdk version "14.0.2" 2020-07-14
    OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12)
    OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)
    

    위와 같이 자바 8이 아닌 다른 버전이 적용되어 있다면 변경한다.

    시스템에 설치되어있는 Java 버전을 조회한다. 기본적으로 macOS 에는 Java 가 설치되어 있다.

    $ /usr/libexec/java_home -V
        14.0.2 (x86_64) "AdoptOpenJDK" - "OpenJDK 14.0.2" /Users/wilder/Library/Java/JavaVirtualMachines/adopt-
        1.8.0_292 (arm64) "Azul Systems, Inc." - "Zulu 8.54.0.21" /Users/wilder/Library/Java/JavaVirtualMachines/azul-1.8.0_292/Contents/Home
    

    Java 8 버전이 있다면 해당 버전으로 변경한다. 없다면 설치를하고 변경 작업을 진행한다.

    $ export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
    
  2. 아래 네 가지 파일을 설치한다. (다운로드 페이지)

    MacOS 환경이라면 아래 명령어로 설치한다.

    MacOS 환경에서 진행하려면 Homebrew 가 필요하다. 설치가 되어있지 않다면 아래 명령어로 설치한다.

    $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    

    이미 설치되어 있다면 Homebrew 를 업데이트 해준다.

    $ brew update
    

    만약 아래와 같은 에러가 발생하면 rm -fr $(brew --repo homebrew/core) 명령어로 brew core directory 를 제거해 주면 해결된다.

    ==> Searching for similarly named formulae...
    Error: No similarly named formulae found.
    ==> Searching for a previously deleted formula (in the last month)...
    Error: No previously deleted formula found.
    ==> Searching taps on GitHub...
    Error: No formulae found in taps.
    
    $ rm -fr $(brew --repo homebrew/core)
    

    Elastic Homebrew 를 Tab 을 설정하여 Homebrew 내의 기본 저장소 외의 서드 파티 저장소를 설정한다.

    $ brew tap elastic/tap
    

    파일을 설치한다.

    $ brew install elastic/tap/elasticsearch-full
    $ brew install elastic/tap/logstash-full
    $ brew install elastic/tap/kibana-full
    $ brew install elastic/tap/filebeat-full
    $ curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.14.0-darwin-x86_64.tar.gz
    

    Ubuntu 환경이라면 아래 명령어로 설치한다.

    $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.14.0-amd64.deb
    $ wget https://artifacts.elastic.co/downloads/logstash/logstash-7.14.0-amd64.deb
    $ wget https://artifacts.elastic.co/downloads/kibana/kibana-7.14.0-amd64.deb
    $ wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.14.0-amd64.deb
    
  3. 설치된 파일을 실행한다.

    MacOS 환경이라면 아래 명령어로 실행시킨다.

    $ brew services start elasticsearch-full
    $ brew services start logstash-full
    $ brew services start kibana-full
    $ brew services start filebeat-full
    

    실행중인 brew services 를 확인할 수 있다.

    $ brew services list
    

    Ubuntu 환경이라면 아래 명령어로 디패키징한다.

    $ sudo dpkg -i elasticsearch-7.14.0-amd64.deb
    $ sudo dpkg -i logstash-7.14.0-amd64.deb
    $ sudo dpkg -i kibana-7.14.0-amd64.deb
    $ sudo dpkg -i filebeat-7.14.0-amd64.deb
    

    여기까지 진행하면 기본적으로 필요한 준비가 끝난다. 설치된 파일은 /etc 경로에서 .yml 등의 파일이 생성된 것을 확인할 수 있다.

  4. Filebeat 를 사용하여 로그파일을 보낸다.

    MacOS 환경이라면 아래 명령어로 설정한다.

    설치한 filebeat-7.14.0-darwin-x86_64/filebeat.yml 파일을 수정한다.

    $ open filebeat-7.14.0-darwin-x86_64/filebeat.yml
    

    29 번째 줄부터 ELK 에 등록할 로그파일의 경로를 적어준다.

    image-20210830024835492

    Ubuntu 환경이라면 아래 명령어로 설정한다.

    여기서 사용될 로그 파일은 Logback 으로 쉽고 편리하게 로그 관리를 해볼까요?에서 생성된 log 파일로 진행한다. 본인이 가지고있는 로그 파일이면 어떤 파일이든 상관없다.

    $ sudo vi /etc/filebeat/filebeat.yml
    

    29 번째 줄에 ELK 에 등록할 로그파일의 경로를 적어준다. 여러 로그 파일을 계속해서 적어줄 수 있다. 여기서는 logback 으로 생성한 로그파일 중 debug.log 에 대해서만 등록해본다.

    image-20210830000922563

    :wq
    

    경로 설정 추가가 완료되면 저장 후 빠져나온다.

  5. 설정 파일의 변경이 생겼으므로 ELK 를 재실행한다.

    MacOS

    $ brew services restart elasticsearch-full
    $ brew services restart kibana-full
    $ brew services restart filebeat-full
    

    Ubuntu

    $ sudo service elasticsearch restart
    $ sudo service kibana restart
    $ sudo service filebeat restart
    
  6. 데이터 베이스를 조회한다.

    http://localhost:9200/_cat/indices?v
    

    위의 주소를 입력하면 Elasticsearch 에 등록된 데이터베이스를 확인할 수 있다.

위의 과정을 통해 기본적인 ELK 설치를 했다. 이제부터 MacOS 기준으로 설명을 진행한다.

로그 수집하기

$ brew services list

위의 명령어를 입력하면 현재 실행중인 서비스를 확인할 수 있다. 그러면 logstasherror 상태인 것을 확인할 수 있는데, 상세한 정보를 확인하기 위해 로그 파일을 조회한다. 사용자마다 경로가 다를 수 있기 때문에 아래 명령어를 사용하면 터미널에서 파일의 경로를 쉽게 찾을 수 있다.

$ sudo find / -name logstash.log

확인 결과 현재 발생된 에러는 pipeline.yml 설정파일이 비어있어서 발생된 것이다. deb 혹은 rpm 으로 설치를 진행한다면 구성파일이 자동으로 배치되지만 macOS 에서 brew 로 진행했기 때문에 없다.

ERROR: Pipelines YAML file is empty.
Location: /opt/homebrew/Cellar/logstash-full/7.14.0/libexec/config/pipelines.yml

$ vi /opt/homebrew/etc/logstash/pipelines.yml

파이프라인 파일을 수정한다. 해당 경로에 파일이 없을 경우 logstash.log 를 찾을 때 사용한 방법으로 pipelines.yml 의 경로를 찾으면 된다. 해당 파일을 찾았으면 에디터로 내용을 추가한다.

  - pipeline.id: sample
    path.config: "/opt/homebrew/etc/logstash/syslog.conf"

Logstash 는 입력, 필터, 출력 단계로 가공이 진행되며, 입력과 출력은 필수다. logstash.yml 파일이 있는 경로에 공식문서를 참고해 syslog.conf 를 만들어본다.

input {
  file {
    path => ["경로/*.log", "경로/파일명" ...]
    start_position => "beginning"
    type => "spring-log"
  }
}

filter {
  if [type] =~ "spring-log" {
    mutate { replace => { "type" => "apache_access" } }
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
      add_field => [ "received_at", "%{@timestamp}" ]
      add_field => [ "received_from", "%{host}" ]
    }
  }
  date {
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "log-demo"
  }
  stdout { codec => rubydebug }
}

syslog.conf 추가가 끝났다면 logstash 를 재실행한다. 만약 logstash 실행 시 -r 옵션을 지정하면 logstash 를 재시작하지 않아도 자동으로 바뀐 환경설정을 로드한다.

$ brew services restart logstash-full

링크