본문 바로가기

카테고리 없음

logstash 실습하기



cd ~/prod/elk/logstash-7.15.0/

# -e 옵션주고, 문자열로 input/output 셋팅하기
./bin/logstash -e 'input { stdin { } } output { stdout { } }'

Successfully started Logstash API endpoint {:port=>9600}

## 에러1(왜 안되는지 모르겟음;)
ERROR: Configuration reloading can't be used with 'config.string' (-e).


# -f 옵션 주고, 파일생성 후 파일경로로 input/output 셋팅하기
cd ~/prod/elk/logstash-7.15.0/
# 파일 생성
touch workshop.conf

# 파일 내용 입력
input {
    stdin { }
}

output {
    stdout { }
}

파일 경로 설정후 logstash 실행
./bin/logstash -f workshop.conf

# -f 옵션 주고, 파일생성 후 파일경로로 input을 tcp로 셋팅 및 output 셋팅하기
# 파일 편집기 실행
cd ~/prod/elk/logstash-7.15.0/
vi workshop.conf

# 파일 내용 수정
input {
tcp {
port => 9900
}
}

output {
stdout { }
}

# logstash 실행
./bin/logstash -f workshop.conf

# 새 터미널 열기 후 9900포트로 문자열 보내기
echo 'Hello Logstash' | nc localhost 9900

# 아래와 같이 받으면 성공
{
       "message" => "Hello Logstash",
      "@version" => "1",
    "@timestamp" => 2022-04-25T05:36:14.367Z,
          "host" => "localhost",
          "port" => 35964
}


# -f 옵션 주고, 파일생성 후 파일경로로 input, 즉 입력을 tcp로 셋팅 및 output, 즉 출력을 elasticsearch로 셋팅하기
# 파일 편집기 실행
vi workshop.conf

# 파일 내용 수정
input {
tcp {
port => 9900
}
}

output {
elasticsearch {
        hosts => ["127.0.0.1:9200"]
    }
}

# kibana 실행
cd ~/prod/elk/kibana-7.15.0-linux-x86_64/bin
./kibana

# logstash 실행
cd ~/prod/elk/logstash-7.15.0/
./bin/logstash -f workshop.conf

#9900포트로 문자열 보내기
echo 'This is logstash to elasticsearch and you can watch it in Kibana' | nc localhost 9900

# kibana 접속
http://localhost:5601/app/dev_tools#/console

GET _cat/indices --> logstash-0000.00.00 라는 index가 생성

GET logstash-*/_search 

# 아래와 같은 결과를 얻을 수 있음.
      {
        "_index" : "logstash-2022.04.25-000001",
        "_type" : "_doc",
        "_id" : "mSpXX4ABzViknMs-_T-U",
        "_score" : 1.0,
        "_source" : {
          "host" : "localhost",
          "port" : 35974,
          "message" : "This is logstash to elasticsearch and you can watch it in Kibana",
          "@timestamp" : "2022-04-25T06:10:43.619Z",
          "@version" : "1"
        }
      }



-----------------------------------------------------------------------------------------------------------------
vi ~/prod/elk/logstash-7.15.0/config/logstash.yml
# logstash를 재실행 없이도 실행 가능하게끔 처리
config.reload.automatic: true

#로그스태시 재시작
cd ~/prod/elk/logstash-7.15.0/
./bin/logstash -f workshop.conf

# weblog-sample.log중 첫줄을 보내기
cd ~/prodlog
head -n 1 ./weblog-sample.log | nc localhost 9900

# 확인을 위해 Kibana로 접속
http://localhost:5601/app/dev_tools#/console

GET logstash-*/_search

# 결과
      {
        "_index" : "logstash-2022.04.25-000001",
        "_type" : "_doc",
        "_id" : "mipcX4ABzViknMs-aj9y",
        "_score" : 1.0,
        "_source" : {
          "host" : "localhost",
          "port" : 35976,
          "message" : "14.49.42.25 - - [12/Aug/2020:01:24:44 +0000] \"GET /articles/ppp-over-ssh/ HTTP/1.1\" 200 18586 \"-\" \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5\"",
          "@timestamp" : "2022-04-25T06:15:33.638Z",
          "@version" : "1"
        }
      },


# 이제 메시지를 입맛에 맞게 가공합시다. Grok 필터 사용

# grok 필터 예제 확인
http://elastic.co/guide/en/logstash/current/plugins-filters-grok.html

---------------------------------------------------  예 제  ------------------------------------------------------
이런 텍스트 메시지가 있다? --> 55.3.244.1 GET /index.html 15824 0.043
%로 묶어서 처리 해줌.
%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

client: 55.3.244.1
method: GET
request: /index.html
bytes: 15824
duration: 0.043
-----------------------------------------------------------------------------------------------------------------

현재 사용하려는 weblog-sample.log 의 아파치 웹로그 처럼 흔하게 쓰이는 건 grok 패턴이 만들어져 있음
https://github.com/logstash-plugins/logstash-patterns-core/tree/main/patterns
legacy 클릭 -> httpd 클릭

COMBINEDAPACHELOG %{HTTPD_COMBINEDLOG} #이놈을 사용하면 됨


# 파일 편집기 실행
cd ~/prod/elk/logstash-7.15.0/
vi workshop.conf

input {
tcp {
port => 9900
}
}

filter{
    grok {
        match => { "message" => "%{COMBINEDAPACHELOG}" } # 메시지 필드를 COMBINEDAPACHELOG 로그 형태로 Grok 필터 적용할 것이다.
    }
}

output {
stdout { }
}

# 결과 --==>> 메시지 필드 외에도 다른 필드들이 생겨남
head -n 1 ./weblog-sample.log | nc localhost 9900

{
       "response" => "200",
          "bytes" => "18586",
           "auth" => "-",
           "verb" => "GET",
       "referrer" => "\"-\"",
           "port" => 35992,
       "clientip" => "14.49.42.25",
        "message" => "14.49.42.25 - - [12/Aug/2020:01:24:44 +0000] \"GET /articles/ppp-over-ssh/ HTTP/1.1\" 200 18586 \"-\" \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5\"",
     "@timestamp" => 2022-04-25T06:39:24.180Z,
           "host" => "localhost",
        "request" => "/articles/ppp-over-ssh/",
          "agent" => "\"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5\"",
          "ident" => "-",
       "@version" => "1",
      "timestamp" => "12/Aug/2020:01:24:44 +0000",
    "httpversion" => "1.1"
}


# 기타 다른 필터
#1. geoip 필터 (ip정보만 가지고, 다양한 정보를 가져옴)
https://www.elastic.co/guide/en/logstash/current/plugins-filters-geoip.html

필수 설정: source / 필드에 ip주소를 적어줘야 함

ex.
geoip {
source => "clientip"
}

# 결과 -->> 아래와 같이 ip(clientip)를 기반으로 한 정보들이 정리되서 나타남
head -n 1 ./weblog-sample.log | nc localhost 9900

...
"geoip" => {
          "country_name" => "South Korea",
              "timezone" => "Asia/Seoul",
        "continent_code" => "AS",
         "country_code3" => "KR",
         "country_code2" => "KR",
              "latitude" => 37.5112,
                    "ip" => "14.49.42.25",
             "longitude" => 126.9741,
              "location" => {
            "lon" => 126.9741,
            "lat" => 37.5112
        }
...

#2. useragent 필터 (agent 정보를 기반으로, Client의 OS정보, 디바이스 정보를 가져옴)

useragent {
source => "agent"  # agent 필드의 내용을 사용
target => "useragent" # useragent라는 필드에 내용을 정리 할 것임
}

# 결과 -->> 아래와 같이 agent필드의 문자열을 기반으로 한 정보들이 정리되서 나타남
...
 "useragent" => {
          "os_major" => "7",
            "device" => "Other",
           "os_name" => "Windows",
           "version" => "3.6.b1",
                "os" => "Windows",
             "minor" => "6",
             "major" => "3",
             "patch" => "b1",
              "name" => "Firefox Beta",
        "os_version" => "7",
           "os_full" => "Windows 7"
    },
...


#3. mutate.convert (grok필터의 경우, 숫자를 문자열로만 받는 경우가 있음 형변환해주는 역할)
ex. "bytes"라는 필드가 사실은 숫자인데, 실제 보면 문자열로 되어있음.
"bytes" => "18586"

mutate {
convert => {
"bytes" => "integer" #바이트 필드를 Integer(숫자)로 바꾼다.
}
}

# 결과 -->> 아래와 같이 bytes필드의 문자열이 숫자로 변경됨.
...
"bytes" => 18586,
...


#4. date 필터
@timestamp필터 --> 날짜타입 / 로그스태시가 실행된 시간
timestamp필터 --> 실제로 로그가 만들어진 시간 (문자열로 되어 있음)

date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]  # "매칭(match)되는 [필드("timestamp"), 형식("25/Apr/2022:16:09:30 +0000")]
target => "logdate"  # 타겟팅할 필드명 설정
}

# 결과 --> 아래와 같이 timestamp를 기반으로한 형식의 logdate필드에 저장됨
...
"logdate" => 2020-08-12T01:24:44.000Z,
...


# elasticsearch로 보내기
output {
    stdout{ }
elasticsearch {
        hosts => ["127.0.0.1:9200"]
    }
}

키바나 페이지 접근
http://localhost:5601/app/dev_tools#/console

# 기존 로그 삭제
DELETE logstash*

# weblog-sample.log중 첫줄을 보내기
cd ~/prodlog
head -n 1 ./weblog-sample.log | nc localhost 9900

# 로그 가져오기
GET logstash-*/_search

# 결과 --> 필터로 셋팅한 값들이 나오게 된다.
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "logstash",
        "_type" : "_doc",
        "_id" : "qiqYX4ABzViknMs-Mz9i",
        "_score" : 1.0,
        "_source" : {
          "response" : "200",
          "bytes" : 18586,
          "geoip" : {
            "country_name" : "South Korea",
            "timezone" : "Asia/Seoul",
            "continent_code" : "AS",
            "country_code3" : "KR",
            "country_code2" : "KR",
            "latitude" : 37.5112,
            "ip" : "14.49.42.25",
            "longitude" : 126.9741,
            "location" : {
              "lon" : 126.9741,
              "lat" : 37.5112
            }
          },
          "auth" : "-",
          "verb" : "GET",
          "referrer" : "\"-\"",
          "port" : 36006,
          "clientip" : "14.49.42.25",
          "logdate" : "2020-08-12T01:24:44.000Z",
          "message" : "14.49.42.25 - - [12/Aug/2020:01:24:44 +0000] \"GET /articles/ppp-over-ssh/ HTTP/1.1\" 200 18586 \"-\" \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5\"",
          "@timestamp" : "2022-04-25T07:20:51.202Z",
          "host" : "localhost",
          "request" : "/articles/ppp-over-ssh/",
          "agent" : "\"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2b1) Gecko/20091014 Firefox/3.6b1 GTB5\"",
          "ident" : "-",
          "useragent" : {
            "os_major" : "7",
            "device" : "Other",
            "os_name" : "Windows",
            "version" : "3.6.b1",
            "os" : "Windows",
            "minor" : "6",
            "major" : "3",
            "patch" : "b1",
            "name" : "Firefox Beta",
            "os_version" : "7",
            "os_full" : "Windows 7"
          },
          "@version" : "1",
          "timestamp" : "12/Aug/2020:01:24:44 +0000",
          "httpversion" : "1.1"
        }
      }
    ]
  }
}