ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Logstash 설치 및 사용법
    LogSystem 2016. 7. 14. 11:13

    Log Stash

    설치

    $ docker pull logstash
    $ docker run -it --rm logstash logstash -e 'input { stdin { } } output { stdout { } }' # 커맨드라인 상에서 실행을 하려면 다음과 같이 사용
    $ docker run -it --rm -v "$PWD":/config-dir logstash logstash -f /config-dir/logstash.conf # logstash.conf파일을 직접 수정해 커맨드라인 상에서 실행을 하고자 할 때
     
    (elasticsearch와 통신할 수 있는지 확인해봐야함)

    문법

    logstash는 입출력 도구이며, input > filter > output 의 pipeline구조로 이루어져 있습니다. 이러한 input, filter, output 설정은 직접 config 파일을 작성하여 설정시켜야 합니다.

    input {
            .
            .
    }
    
    filter {
            .
            .
    }
    
    output {
            .
            .
    }

    예제

    가장 기본적인 설정으로 커맨드라인으로 사용자에게 입력을 받고 출력을 하는 설정으로 예제를 시작하겠습니다. 

    $ cat logstash.conf
     
    input {
    		stdin {}
    }
     
    output {
    		stdout {
    				codec =>  rubydebug {}
    		}
    }
     
    $ docker run -it --rm -v $HOME/logstash:/config-dir logstash logstash -f /config-dir/logstash.conf
    Settings: Default pipeline workers: 2
    Pipeline main started
    hello world! ### hello world!를 입력
    {
           "message" => "hello world!",
          "@version" => "1",
        "@timestamp" => "2016-07-12T11:25:48.536Z",
              "host" => "61b494acbb39"
    }

    stdout 설정에 codec으로 rubydebug를 추가했는데 출력을 보기좋은 json 포맷으로 보여줍니다. 여기서 message, @version, @timestamp, host 필드는 logstash에 내장되어 있는 필드입니다.

    filter

    filter설정을 적용하면, 입력으로 들어온 데이터를 가공하는 작업을 할 수 있습니다. 예를 들어, json 형식으로 input 되었다면 json의 필드를 추가, 삭제, 필드의 값을 조작할 수 있습니다. 

    다음 json 데이터를 가공하는 예제를 하기 위해 config 파일을 설정합니다.

    $ cat logstash.conf
     
    input {
            stdin { }
    }
    
    filter {
            json {
                    source => "message"
                    add_field => { "add_key1" => "add_value1"  }
                    add_field => { "add_key2" => "add_value2 %{value}" }
                    remove_field => [ "age" ]
            }
    }
    
    output {
            stdout {
                    codec => rubydebug { }
            }
    }

    filter로 json을 추가하여 정의를 했습니다. source 설정은 가공할 데이터가 들어 있는 필드를 말합니다. (output의 필드) add_field는 출력 시, 필드를 추가하는 것으로 위에서 고정한 값을 출력할 수도 있고 기존 source 데이터의 필드값을 '%{필드명}'을 사용해 출력할 수도 있습니다. (연산이 가능한지 테스트 요망)


    $ docker run -it --rm -v $HOME/logstash:/config-dir logstash logstash -f /config-dir/logstash.conf
    Settings: Default pipeline workers: 2
    Pipeline main started
    {"name":"lee", "age":"11", "value":"edit value?"}  ### json 데이터를 입력, 형식이 json이 아닐 시, 에러
    {
           "message" => "{\"name\":\"lee\", \"age\":\"11\", \"value\":\"edit value?\"}",
          "@version" => "1",
        "@timestamp" => "2016-07-12T11:41:20.594Z",
              "host" => "c6ee75a7e14d",
              "name" => "lee",
             "value" => "edit value?",
          "add_key1" => "add_value1",
          "add_key2" => "add_value2 edit value?"
    }

    결과로는 추가하고자 하는 필드 2개(add_key1, add_key2) 와 삭제하고자 하는 필드 1개(age)가 업데이트가 된 것을 확인할 수 있습니다.

    플러그인

    input, output, filter, codec의 플러그인은 매우 많기 때문에 아래의 링크에서 확인해 필요한 플러그인을 사용해야 합니다. (elasticsearch의 색인작업을 해주는 output 플러그인도 존재)

    Elastic Search와 연동

    elasticsearch의 output 플러그인은 node, transport, http 3가지 프로토콜이 있습니다. 여기서는 elasticsearch 클러스터의 9200번 포트로 직접 접속해 데이터를 전송해주는 방식인 http 프로토콜을 사용해 연동합니다.

    현재 output 플러그인의 elastic search는 http 프로토콜만 지원하고 있습니다. 

    다음과 같이 config 파일을 수정해 줍니다. 

    $ cat logstash.conf
    input {
            stdin {
                    codec => json
            }
    }
    output {
            elasticsearch {
                    hosts => "elasticsearch ip:port"
                    index => "school"
                    document_type => "students"
            }
            stdout {
                    codec => rubydebug { }
            }
    }
     
    $ docker run -it --rm -v $HOME/logstash:/config-dir logstash logstash -f /config-dir/logstash.conf
    Settings: Default pipeline workers: 2
    Pipeline main started
    {"name":"lee", "class":"a"} # 다음과 같이 json 전달
    {
              "name" => "lee",
             "class" => "a",
          "@version" => "1",
        "@timestamp" => "2016-07-13T11:01:48.959Z",
              "host" => "2ecc38a0f260"
    }

    출력이 정상적으로 잘 되어 head 플러그인을 확인해 봅니다.


    원래는 Jordan Seberius라는 노드 1개만 생성했지만 색인작업을 진행하였더니 Unassigned가 생성되었습니다. (노드가 1개라 그런지 설정을 잘못해서 그런지 확인필요)


    두번째 row를 보면 위 logstash.conf 파일에서 설정해 준 대로, 'school' 인덱스와 'students' 타입이 동적으로 생성되며, 색인이 성공했음을 확인 할 수 있습니다. 


    더 자세한 내용은 https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html를 참고하면 됩니다.

    Template 사용 - 확인 필요

    템플릿을 사용해 미리 index와 type의 스키마를 정해놓고 데이터를 색인할 수 있습니다.

    $ curl -XPUT 'elasticsearch ip:9200/_template/school?pretty' -d '{
    >     "template" : "school",
    >     "settings" : { "index.refresh_interval" : "5s" },
    >     "mappings" : {
    >         "students" : {
    >             "properties" : {
    >                 "class" : { "type" : "string", "store" : "yes", index : "not_analyzed" },
    >                 "name" : { "type" : "string",  "store" : "yes" },
    >                 "address" : { "type" : "string",  "store" : "yes" }
    >             }
    >         }
    >     }
    > }'
    {
      "acknowledged" : true
    }

    'students'라는 인덱스 템플릿을 위처럼 rest api로 생성했고 "acknowledged" : true 로 생성이 정상적으로 된 것을 확인 할 수 있습니다.

    다음, logstash가 해당 템플릿을 사용해 색인할 수 있도록 설정해야합니다.

    elasticsearch {
                    host => "localhost"
                    index => "school"
                    index_type => "students"
                    protocol => "http"
                    template_name => "school" # 바로 여기 설정
            }
    }
     
    $ docker run -it --rm -v $HOME/logstash:/config-dir logstash logstash -f /config-dir/logstash.conf
    Settings: Default pipeline workers: 2
    Pipeline main started
    { "class" : "A", "name" : "iron man", "address" : "newyork" }
    {
             "class" => "A",
              "name" => "iron man",
           "address" => "newyork",
          "@version" => "1",
        "@timestamp" => "2016-07-13T10:49:13.128Z",
              "host" => "6cdf7452aea1"
    }

    템플릿을 적용하지 않은 경우


    Elasticsearch의 기본 idea는 realtime 으로 document를 색인하는것이여서 동적으로 인덱스와 타입이 생성됩니다. 위의 경우는 정해진 스키마없이 동적으로 인덱스와 타입이 생성된 경우이며 dynamic_templates 라는 기본 템플릿이 적용됩니다.

    템플릿을 적용한 경우


    위에서 생성한 템플릿의 필드설정대로, 'class' 필드는 index 설정이 'not_analyzed'로 되어있습니다. 템플릿이 정상적으로 적용되어 데이터가 색인되었다는 증거입니다.

    templates에 관해 더 자세한 것은 https://www.elastic.co/guide/en/elasticsearch/reference/2.3/indices-templates.html에서 확인할 수 있습니다.

    댓글