모도리 avatar

ELK Stack을 이용한 로그 관제 시스템 만들기

modolee

Published: 26 Mar 2019 › Updated: 26 Mar 2019ELK Stack을 이용한 로그 관제 시스템 만들기

ELK Stack을 이용한 로그 관제 시스템 만들기


안녕하세요. 개발자 모도리입니다.
서비스 운영 중 로그 관리가 필요하여 예전에 구축했었던 ELK를 이용한 로그 관제 시스템을 다시 구성해 봤습니다.

ELK(ElasticSearch, LogStash, Kibana) 설치

구조도

  • 로그를 생성하는 서버들에 Filebeat를 설치하고, 로그를 집계할 서버에 ELK를 설치한다.
  • Filebeat에서 LogStash로 로그를 전송하고 LogStash에서 한번 필터링을 거친 로그들이 ElasticSearch에 저장된다.
  • 저장 된 로그는 Kibana를 통해서 시각화하여 볼 수 있다.

권장 사항

  • 메모리 4GB 이상 (ELK를 한 대에 서버에 설치할 경우)
  • JAVA 8 사용

JAVA 설치

Repository 추가 및 설치

sudo add-apt-repository ppa:webupd8team/java

sudo apt update

sudo apt install oracle-java8-installer

sudo apt install oracle-java8-set-default

자바 버전 확인

java -version

ElasticSearch 설치 (Log 수집 서버, Ubuntu)

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.2.deb

sudo dpkg -i elasticsearch-6.6.2.deb

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl daemon-reload

sudo systemctl enable elasticsearch.service

sudo systemctl start elasticsearch.service

sudo systemctl status elasticsearch.service

  elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-03-25 11:58:03 UTC; 13min ago

(나중에 필요한 경우) 서비스 등록 해지 및 중지

sudo systemctl disable elasticsearch.service

sudo systemctl stop elasticsearch.service

설치 확인

curl -X GET "localhost:9200/"

{
  "name" : "xQub8IM",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "7RLVGGnxR6qHbV9mYqA_mg",
  "version" : {
    "number" : "6.6.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "3bd3e59",
    "build_date" : "2019-03-06T15:16:26.864148Z",
    "build_snapshot" : false,
    "lucene_version" : "7.6.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
 }

Kibana 설치 (Log 수집 서버, Ubuntu)

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/kibana/kibana-6.6.2-amd64.deb

sudo dpkg -i kibana-6.6.2-amd64.deb

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl enable kibana.service

sudo systemctl start kibana.service

sudo systemctl status kibana.service

  kibana.service - Kibana
   Loaded: loaded (/etc/systemd/system/kibana.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-03-25 11:58:03 UTC; 13min ago

설치 확인

curl -v [Log 수집 서버 IP]:5601

* Rebuilt URL to: localhost:5601/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5601 (#0)
> GET / HTTP/1.1
> Host: localhost:5601
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< location: /app/kibana
< kbn-name: kibana
< kbn-xpack-sig: 292ada877125f67092b9a6a4b59b08ca
< content-type: text/html; charset=utf-8
< cache-control: no-cache
< content-length: 0
< connection: close
< Date: Tue, 26 Mar 2019 02:11:00 GMT
< 
* Closing connection 0

LogStash 설치 (Log 수집 서버, Ubuntu)

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/logstash/logstash-6.6.2.deb

sudo dpkg -i logstash-6.6.2.deb

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl enable logstash.service

sudo systemctl start logstash.service

sudo systemctl status logstash.service

  logstash.service - logstash
   Loaded: loaded (/etc/systemd/system/logstash.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-03-25 12:10:22 UTC; 17s ago

FileBeat 설치 (Log 생성 서버, Amazon Linux(CentOS 계열))

파일 다운로드 및 설치

wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.6.2-x86_64.rpm

sudo rpm -vi filebeat-6.6.2-x86_64.rpm

시스템에 서비스 등록, 시작 및 상태 확인

sudo systemctl enable filebeat.service

sudo systemctl start filebeat.service

sudo systemctl status filebeat.service

  filebeat.service - Filebeat sends log files to Logstash or directly to Elasticsearch.
   Loaded: loaded (/usr/lib/systemd/system/filebeat.service; enabled; vendor preset: disabled)
   Active: active (running) since  2019-03-25 21:41:23 KST; 51s ago

환경 설정

ElasticSearch

설정 파일 수정

sudo vi /etc/elasticsearch/elasticsearch.yml

  • ElasticSearch와 binding 할 IP 주소를 설정한다. (port는 수정 안 할 경우 기본 9200)
network.host : 0.0.0.0

서비스 재시작

sudo systemctl restart elasticsearch.service

Kibana

설정 파일 수정

sudo vi /etc/kibana/kibana.yml

  • Kibana와 binding할 IP 주소를 설정한다. (port는 수정 안 할 경우 기본 5601)
server.host : "0.0.0.0"
elasticsearch.url : "http://elasticsearch_server_address:9200"

서비스 재시작

sudo systemctl restart kibana.service

LogStash

설정 파일 생성

sudo vi /etc/logstash/conf.d/kstarlive-web.conf

input {
 beats {
   port => 5044
 }
}

filter {
  if [fields][log_type] == "nginx_access" {
    grok {
      match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\"\"%{DATA:[nginx][access][agent]}\""] }
      remove_field => "message"
    }
    mutate {
      add_field => { "read_timestamp" => "%{@timestamp}" }
    }
    date {
      match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
      remove_field => "[nginx][access][time]"
    }
    useragent {
      source => "[nginx][access][agent]"
      target => "[nginx][access][user_agent]"
      remove_field => "[nginx][access][agent]"
    }
    geoip {
      source => "[nginx][access][remote_ip]"
      target => "[nginx][access][geoip]"
    }
  }
}

output {
  if([fields][log_type] == "nginx_access") {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "access-log-%{+YYYY.MM.dd}"
    }
  }
  else if([fields][log_type] == "nginx_error") {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "error-log-%{+YYYY.MM.dd}"
    }
  }
  else if([fields][log_type] == "laravel") {
    elasticsearch {
      hosts => ["localhost:9200"]
      index => "laravel-log-%{+YYYY.MM.dd}"
    }
  }
}
  • filebeat에서 로그 데이터를 받아서 log_type에 따라서 별도의 index를 사용해서 elasticsearch에 저장 하는 설정
  • logstash 필터링 설정 참고

서비스 재시작

sudo systemctl restart logstash.service

Filebeat

모듈 설치 및 설정

  • nginx 모듈 사용 설정

sudo filebeat modules enable nginx

  • 설정 된 모듈 확인

sudo filebeat modules list

  • 초기 환경 설정

sudo filebeat setup -e

  • 모듈 설정 파일 수정

sudo vi /etc/filebeat/modules.d/nginx.yml

- module: nginx
  # Access logs
  access:
    enabled: true
    input:
      fields:
        server_name: dev-web
        log_type: nginx_access
    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/home/ec2-user/kstarlive_web/storage/logs/nginx/access.log"]

  # Error logs
  error:
    enabled: true
    input:
      fields:
        server_name: dev-web
        log_type: nginx_error

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/home/ec2-user/kstarlive_web/storage/logs/nginx/error.log"]

설정 파일 수정

sudo vi /etc/filebeat/filebeat.yml

#=========================== Filebeat inputs =============================
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /home/ec2-user/kstarlive_web/www/storage/logs/*.log
  fields:
    server_name: dev-web
    log_type: laravel

#-------------------------- Elasticsearch output ------------------------------
#output.elasticsearch:

#----------------------------- Logstash output --------------------------------
output.logstash:
  # The Logstash hosts
  hosts: ["10.0.1.45:5044"]
  • laravel에서 발생하는 에러 로그를 수집하기 위한 설정. fields는 추가 데이터를 지정하는 부분 kibana에서 server_name 별로 필터링해서 보여주고자 할 때 이런식으로 각 서버 마다 server_name을 다르게 설정하면, 원하는 서버만 필터링해서 보기 편하다. elasticsearch에 바로 데이터를 보내지 않고, logstash를 거치기 때문에 elasticsearch 설정은 주석 처리한다.

서비스 재시작

sudo systemctl restart filebeat.service

시각화

  • 브라우저에 [Kibana가 설치 된 서버 주소]:5601 를 입력하여 Kibana에 접속한다.

인덱스 패턴 만들기

  • 좌측 메뉴 Management에 들어가서 Kibana > Index Patterns 선택

  • Create index pattern을 누르면 Define index pattern 라는 입력창이 나온다.
  • LogStash에서 output으로 나오게 한 index 종류들이 나오는데 묶어서 볼 것 로그들의 패턴을 입력한다.

  • access-log-* 과 같은 형식으로 입력하면 access log만 모아서 볼 수 있다.
  • 패턴 입력 후 Next step을 누르면 Time Filter field name을 선택하는 화면이 나오는데, @timestamp를 선택한다.

데이터 탐색하기

  • 좌측 메뉴 Discover에 들어가서, Add a filter + 밑의 드롭다운 메뉴에서 만들어 놓은 인덱스를 선택한다.

  • 보고 싶은 필드를 확인하고 add 버튼을 눌러서 해당 필드만 볼 수 있도록 한다.
  • filebeat 설정에서 추가했던 fields.log_type, fields.server_name가 있는 것을 확인할 수 있다.

  • 해당 데이터 중 특정 값을 필터링하려면 Add a filter + 버튼을 눌러서 특정 필드를 선택하고 is, is not 등을 선택하고 원하는 값을 입력한다.

  • 상단의 Save 버튼을 눌러서 필터링 된 결과를 저장한다.

그래프 만들기

  • 좌측의 Visualize 메뉴를 선택하고 + 버튼을 누른다.
  • 원하는 시각화 컴포넌트 종류를 선택한다.

  • Horizontal Bar를 선택한 경우

  • Buckets > X-Axis를 클릭하고, Aggregation에서 Filters를 선택한다.

  • Add filter를 눌러서 filter, filter label을 입력하고 상단의 ▶︎ 버튼을 눌러서 오른쪽에서 미리보기를 확인한다.

  • 상단의 Save를 눌러서 시각화 한 화면을 저장한다.

대시보드 구성하기

  • 좌측 메뉴에 Dashboard를 선택하고 Create new dashboard 눌러서 새로운 대시보드 화면을 만든다.
  • 상단의 Add를 누르면 데이터 탐색하기, 그래프 만들기 에서 저장 한 시각화 검색 결과를 불러올 수 있다.

  • 원하는 구성을 만든 후 저장한다.

트러블 슈팅

JAVA 버전 문제

Unrecognized VM option 'UseParNewGC'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
chmod: cannot access '/etc/default/logstash': No such file or directory

메모리 부족 문제

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000ca660000, 899284992, 0) failed; error='Cannot allocate memory' (errno=12)

디스크 부족 문제

[2019-03-26T04:35:00,614][INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 403 ({"type"=>"cluster_block_exception", "reason"=>"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"})
  • 디스크 부족할 경우 발생, 용량을 늘려준다.
  • read only로 설정 된 값을 풀어준다.
    • curl -X PUT "localhost:9200/*/_settings" -H 'Content-Type: application/json' -d'{"index.blocks.read_only_allow_delete": null}'
  • 오래된 index를 삭제한다.

참고


  • 저는 블록체인 개발사 (주)34일에서 블록체인 엔지니어로 일하고 있습니다.
  • 880만 팔로워 전세계 1위 한류 미디어 케이스타라이브(KStarLive)와 함께 만든 한류 플랫폼에서 사용되는 케이스타코인(KStarCoin) 프로젝트를 진행 중입니다. 팬 커뮤니티 활동을 하면서 코인을 얻을 수 있으며, 한류 콘텐츠 구매, 공연 예매, 한국 관광 상품 구매, 기부 및 팬클럽 활동 등에 사용 될 계획입니다.

Leave ELK Stack을 이용한 로그 관제 시스템 만들기 to:

Written by

블록체인에 관심이 많은 개발자입니다.

Read more #elk posts


Best Posts From 모도리

We have not curated any of modolee's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From 모도리