Logstash, ElasticSearch, Kibana 이것들은 무엇인가?

문서 업데이트 (2014-08-27)

– Logstash
각종 로그를 가져오는 용도로 사용 됩니다.

– ElasticSearch
Lucene을 바탕으로 개발한 분산 검색 엔진입니다.

– Kibana
ElasticSearch의 저장 된 데이터를 Dashboard 형태로 보여줍니다.

실시간 로그 분석 시스템의 구성도는 어떻게 되는가?
Logstash에서 1.2.2 기준으로 추천하는 구성도 입니다.
이전 버전에서는 Redis 대신 RabbitMQ를 사용했었는데 복잡성 때문에 Redis를 사용하기 시작 했다고 합니다.
Redis를 사용하는 이유는 Logstash에서 가져온 데이터를 디스크 I/O를 거치지 않고 Memory로 처리 하도록 사용됩니다.

getting-started-centralized-overview-diagram

실시간 로그 분석 시스템을 실제로 만들어 보자.
본 글은 CentOS 6.4(x86_64)에서 테스트 되었고 테스트 용도로 구축한 것이기 때문에 한 서버에 모든 프로그램이 동작하게 됩니다.
따라서, 실서버에 적용시 각각의 프로그램 용도에 맞게 분산해서 구축 하셔야 합니다.
설치 순서는 Nginx -> Redis -> JDK -> ElasticSearch -> Logstash -> Kibana 가 되겠습니다.

1. Nginx 설치
Nginx의 저장소 추가하여 설치를 진행합니다.

[root@ruo91 ~]# nano /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=0
[root@ruo91 ~]# yum --enablerepo=nginx install -y nginx

 

– nginx.conf 설정
Access 로그가 JSON 포멧 방식으로 저장 되도록 설정합니다.

[root@ruo91 ~]# nano /etc/nginx/nginx.conf
user  nginx;
access_log   off;
error_log  /var/log/nginx/error.log warn;
pid/var/run/nginx.pid;

worker_processes  1;
events {
  worker_connections  1024;
}

http {
 include   /etc/nginx/mime.types;
 default_type  application/octet-stream;
 sendfileon;
 #tcp_nopush on;
 keepalive_timeout  65;
 #gzip  on;

 # JSON
 log_format json_format '{ "@time": "$time_iso8601", '
  '"@fields": { '
  '"country": "$http_cf_ipcountry", '
  '"ip": "$remote_addr", '
  '"status": "$status", '
  '"request": "$request", '
  '"size": "$body_bytes_sent", '
  '"user-agent": "$http_user_agent", '
  '"referrer": "$http_referer" } }';

 # yongbok.net
 server {
  listen  80;
  server_name yongbok.net www.yongbok.net;
  root   /home/ruo91/public_html;
  index  index.html;

  # Logs
  access_log  /storage/logs/www-access.json json_format;
  error_log /storage/logs/www-error.log;
 }
}

 

JSON 포멧의 Access 로그는 아래와 같이 저장이 됩니다. (원래는 한줄로 기록 됩니다.)

{ 
"@time": "2013-11-03T15:12:57+09:00",
"@fields":
 { 
  "country": "US",
  "ip": "66.249.73.31",
  "status": "200",
  "request": "GET /blog/page/25/ HTTP/1.1",
  "size": "16253",
  "user-agent": "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
  "referrer": "-" 
 }
}

 

2. Redis 설치

소스로 설치하기를 원하시는 분들은 http://redis.io/download 를 참고 하시기 바랍니다.

[root@ruo91 ~]# yum install -y redis

 

– Redis 실행

[root@ruo91 ~]# service redis start

 

3. JDK 설치
Oracle JDK (Java Development Kit)을 적절한 곳에 설치 합니다.
http://www.oracle.com/technetwork/java/javase/downloads/index.html

[root@ruo91 ~]# curl -LO "http://download.oracle.com/otn-pub/java/jdk/8u20-b26/jdk-8u20-linux-x64.tar.gz" \
-H 'Cookie: oraclelicense=accept-securebackup-cookie'
[root@ruo91 ~]# tar xzf jdk-8u20-linux-x64.tar.gz
[root@ruo91 ~]# mv jdk1* /usr/local/jdk
[root@ruo91 ~]# echo '# JDK' >> ~/.bash_profile
[root@ruo91 ~]# echo 'export JAVA_HOME=/usr/local/jdk' >> ~/.bash_profile
[root@ruo91 ~]# echo 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bash_profile
[root@ruo91 ~]# source ~/.bash_profile

 

4. ElasticSearch 설치
http://www.elasticsearch.org/

[root@ruo91 ~]# wget -P /opt https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.3.2.tar.gz
[root@ruo91 ~]# tar xzvf elasticsearch/elasticsearch-1.3.2.tar.gz
[root@ruo91 ~]# cd elasticsearch-1.3.2
[root@ruo91 ~]# echo '# Elasticsearch' >> ~/.bash_profile
[root@ruo91 ~]# echo 'export ES_HOME=/opt/elasticsearch-1.3.2' >> ~/.bash_profile
[root@ruo91 ~]# echo 'export PATH=$PATH:$ES_HOME/bin' >> ~/.bash_profile

 

ElasticSearch의 모니터링을 위한 Plugin 설치 (head, bigdesk, kopf)

[root@ruo91 ~]# plugin -install mobz/elasticsearch-head
[root@ruo91 ~]# plugin -install lukas-vlcek/bigdesk
[root@ruo91 ~]# plugin -install lmenezes/elasticsearch-kopf

 

– ElasticSearch 실행

0.x 버전대에서는 -f 옵션을 주어 포그라운드로 실행 시켰지만, 1.x 버전대 부터는 -d 옵션으로 데몬 형태로 실행할수 있습니다.

[root@ruo91 ~]# elasticsearch
[2014-08-27 12:51:09,355][INFO ][node                     ] [Dredmund Druid] version[1.3.2], pid[19297], build[dee175d/2014-08-13T14:29:30Z]
[2014-08-27 12:51:09,356][INFO ][node                     ] [Dredmund Druid] initializing ...
[2014-08-27 12:51:09,364][INFO ][plugins                  ] [Dredmund Druid] loaded [], sites [kopf, bigdesk, head]
[2014-08-27 12:51:11,468][INFO ][node                     ] [Dredmund Druid] initialized
[2014-08-27 12:51:11,468][INFO ][node                     ] [Dredmund Druid] starting ...
[2014-08-27 12:51:11,643][INFO ][transport                ] [Dredmund Druid] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/yongbok.net:9300]}
[2014-08-27 12:51:11,694][INFO ][discovery                ] [Dredmund Druid] elasticsearch/iSuwRafARpGy4juJhYGATg
[2014-08-27 12:51:14,720][INFO ][cluster.service          ] [Dredmund Druid] new_master [Dredmund Druid][iSuwRafARpGy4juJhYGATg][ruo91][inet[/yongbok.net:9300]], reason: zen-disco-join (elected_as_master)
[2014-08-27 12:51:14,766][INFO ][gateway                  ] [Dredmund Druid] recovered [0] indices into cluster_state
[2014-08-27 12:51:14,771][INFO ][http                     ] [Dredmund Druid] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/yongbok.net:9200]}
[2014-08-27 12:51:14,772][INFO ][node                     ] [Dredmund Druid] started

 

5. Logstash 설치

1.2.x 버전까지는 jar 형태로 배포되었지만, 1.4 .x 버전부터 tar.gz 형태로 배포 됩니다. (http://logstash.net/)

[root@ruo91 ~]# wget -P /opt https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz
[root@ruo91 ~]# echo '# Logstash' >> ~/.bash_profile
[root@ruo91 ~]# echo 'export LS_HOME=/opt/logstash-1.4.2' >> ~/.bash_profile
[root@ruo91 ~]# echo 'export PATH=$PATH:$LS_HOME/bin' >> ~/.bash_profile

 

– Logstash log shipper

Logstash의 경우 버전업이 됨에 따라 설정 파일의 문법이 약간 달라질 경우가 있으므로,  공식문서를 참고 하셔서 설정 하시기 바랍니다.

이 설정 파일의 경우 Nginx에서 발생 되는 Access 로그 파일을 가져와서 Redis로 전달 해주는 역할을 담당 합니다.

[root@ruo91 ~]# nano /opt/dev/logstash-shipper.conf
input {
  file {
   path => "/storage/logs/www-access.json" # Nginx의 Access 로그
   type => nginx
   format => json
  # message_format => json
  # format => msgpack_event
  # message_format => json_event
  }
}
output {
  stdout { codec => rubydebug }
  redis { 
   host => "127.0.0.1"
   port => "6379"
   data_type => "list"
   key => "logstash"   # Redis에 저장시 사용할 Key 이름
  }
}

 

– Logstash log shipper 실행

실행 전 반드시 설정파일에 문제가 없는지 확인 후 실행 하도록 합니다. (log shipper를 실행과 동시에 Redis로 저장이 됩니다.)

[root@ruo91 ~]# logstash -f /opt/logstash-shipper.conf -t
Configuration OK
[root@ruo91 ~]# logstash -f /opt/logstash-shipper.conf
{
         "@time" => "2014-08-27T13:13:57+09:00",
       "@fields" => {
           "country" => "US",
              "host" => "66.249.74.135",
            "status" => "200",
           "request" => "GET /blog/page/6/?commentId=7 HTTP/1.1",
              "size" => "19932",
        "user-agent" => "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
          "referrer" => "-"
    },
      "@version" => "1",
    "@timestamp" => "2014-08-27T04:13:58.176Z",
          "type" => "nginx",
          "host" => "ruo91",
          "path" => "/storage/logs/www-access.json"
}

 

– Logstash Indexer
Indexer는 Redis에 저장 된 데이터를 ElasticSearch로 전송 하는 역할을 담당 합니다.

[root@ruo91 ~]# nano /opt/logstash-indexer.conf
input {
  redis {
   # redis 설정 값은 logstash-shipper.conf 설정과 동일 해야 합니다.
   host => "127.0.0.1"
   port => "6379"
   data_type => "list"
   key => "logstash"
   # json event를 Redis에서 가져오기 위해 json 코덱을 사용합니다.
   codec => json
  }
}
output {
  stdout { codec => rubydebug codec => json }
  elasticsearch { 
	host => "127.0.0.1" 
  }
}

 

– Logstash Indexer 실행

Redis에 저장된 데이터를 한번에 가져오는 것을 확인 할수 있습니다.

[root@ruo91 ~]# logstash -f /opt/logstash-indexer.conf -t
Configuration OK
[root@ruo91 ~]# logstash -f /opt/logstash-indexer.conf
{
         "@time" => "2014-08-27T13:20:25+09:00",
       "@fields" => {
           "country" => "US",
              "host" => "65.19.138.33",
            "status" => "304",
           "request" => "GET /blog/feed/ HTTP/1.1",
              "size" => "1",
        "user-agent" => "Feedly/1.0 (+http://www.feedly.com/fetcher.html; like FeedFetcher-Google)",
          "referrer" => "-"
    },
      "@version" => "1",
    "@timestamp" => "2014-08-27T13:20:25.804+09:00",
          "type" => "nginx",
          "host" => "ruo91",
          "path" => "/storage/logs/www-access.json"
}

 

ElasticSearch의 head 플러그인을 통해 logstash index가 생성 되어 데이터가 들어가 있는지 확인 해봅니다.

elasticsearch-plugin-head

잘 들어 있네요.
elasticsearch-plugin-head-browser

 

5. Kibana 설치
Kibana는 Logstash를 logstash-web으로 구동했을때와 ElasticSearch의 Plugin으로 설치 했을때 모두 사용이 가능합니다.
Nginx 웹서버를 이미 사용중이므로 가상호스트 사용자의 public_html 디렉토리에 바로 넣어 설치 하겠습니다.

[root@ruo91 ~]# git clone https://github.com/elasticsearch/kibana.git
[root@ruo91 ~]# mv kibana/src /home/ruo91/public_html/kibana
[root@ruo91 ~]# chown -R ruo91:ruo91 /home/ruo91/public_html/kibana

 

– Kibana 설정
config.js에서 ElasticSearch의 서버 아이피와 kibana_index를 수정합니다.
kibana_index는 logstash-indexer가 index를 logstash-2013.11.04 형태로 생성 하므로 와일드 카드로 주면 날짜와 상관 없이 불러 올수 있습니다.

[root@ruo91 ~]# su - ruo91
[ruo91@ruo91 ~]$ nano public_html/kibana/config.js
/**
 * These is the app's configuration, If you need to configure
 * the default dashboard, please see dashboards/default
 */
define(['settings'],
function (Settings) {

  return new Settings({
/**
 * URL to your elasticsearch server. You almost certainly don't
 * want 'http://localhost:9200' here. Even if Kibana and ES are on
 * the same host
 *
 * By default this will attempt to reach ES at the same host you have
 * elasticsearch installed on. You probably want to set it to the FQDN of your
 * elasticsearch host
 * @type {String}
 */
/* elasticsearch: "http://"+window.location.hostname+":9200", */
elasticsearch: "http://localhost:9200",
/**
 * The default ES index to use for storing Kibana specific object
 * such as stored dashboards
 * @type {String}
 */
kibana_index: "logstash-*",
/**
 * Panel modules available. Panels will only be loaded when they are defined in the
 * dashboard, but this list is used in the "add panel" interface.
 * @type {Array}
 */
panel_names: [
  'histogram',
  'map',
  'pie',
  'table',
  'filtering',
  'timepicker',
  'text',
  'fields',
  'hits',
  'dashcontrol',
  'column',
  'derivequeries',
  'trends',
  'bettermap',
  'query',
  'terms',
  'sparklines'
]
  });
});

 

– Kibana 웹으로 확인
http://your-domain.com/kibana/ 에 접속해서 실시간으로 로그를 분석할수 있게 됩니다.
kibana

kibana2

감사합니다. 😀