Logstash
출처: 문서
본문
Logstash
Logstash는 실시간 이벤트 처리 엔진이에요. OpenSearch, Beats, OpenSearch Dashboards를 포함하는 OpenSearch 스택의 일부예요.
다양한 소스에서 Logstash로 이벤트를 보낼 수 있어요. Logstash는 이벤트를 처리해서 하나 이상의 목적지로 보내요. 예를 들어 웹 서버의 액세스 로그를 Logstash로 보낼 수 있어요. Logstash는 각 로그에서 유용한 정보를 추출해서 OpenSearch 같은 목적지로 보내요.
Logstash로 이벤트를 보내면 이벤트 처리를 앱에서 분리할 수 있어요. 앱은 이벤트를 Logstash로 보내기만 하면 되고, 그 이후에 이벤트에 어떤 일이 일어나는지는 전혀 알 필요가 없어요.
오픈 소스 커뮤니티는 원래 로그 데이터를 처리하기 위해 Logstash를 만들었지만, 이제는 XML이나 JSON 형식의 이벤트를 포함해 어떤 유형의 이벤트든 처리할 수 있어요.
파이프라인 구조
Logstash는 입력, 필터, 출력이라는 세 단계로 이루어진 파이프라인을 구성하는 방식으로 동작해요.
각 단계는 하나 이상의 플러그인을 사용해요. Logstash에는 200개가 넘는 내장 플러그인이 있어서 필요한 걸 찾을 가능성이 높아요. 내장 플러그인 외에도 커뮤니티에서 제공하는 플러그인을 사용하거나 직접 작성할 수도 있어요.
파이프라인의 구조는 다음과 같아요:
input {
input_plugin => {}
}
filter {
filter_plugin => {}
}
output {
output_plugin => {}
}
여기서:
input은 여러 소스에서 로그 같은 이벤트를 동시에 받아요. Logstash는 TCP/UDP, 파일, syslog, Microsoft Windows EventLogs,stdin, HTTP 등을 위한 다양한 입력 플러그인을 지원해요. 이벤트를 수집할 때는 Beats라는 오픈 소스 입력 도구 모음을 사용할 수도 있어요. 입력 플러그인은 이벤트를 필터로 보내요.filter는 이벤트를 여러 방식으로 파싱하고 보강해요. Logstash에는 이벤트를 수정해서 출력으로 전달하는 필터 플러그인이 많이 있어요. 예를 들어grok필터는 비정형 이벤트를 필드로 파싱하고,mutate필터는 필드를 변경해요. 필터는 순차적으로 실행돼요.output은 필터링된 이벤트를 하나 이상의 목적지로 보내요. Logstash는 OpenSearch, TCP/UDP, 이메일, 파일,stdout, HTTP, Nagios 같은 목적지를 위한 다양한 출력 플러그인을 지원해요.
입력 단계와 출력 단계 모두 이벤트가 파이프라인에 들어가거나 나올 때 이를 처리하는 코덱을 지원해요.
널리 쓰이는 코덱으로는 json과 multiline이 있어요. json 코덱은 JSON 형식의 데이터를 처리하고, multiline 코덱은 여러 줄 이벤트를 한 줄로 합쳐요.
파이프라인 설정 안에 조건문을 작성해서 특정 조건이 충족될 때 특정 동작을 수행하게 할 수도 있어요.
Logstash 설치
OpenSearch에서 Logstash를 설치하려면 다음 단계에서 설명하는 대로 먼저 클러스터에 Logstash를 설치하고, 그다음 OpenSearch Logstash 플러그인을 설치하세요.
Tarball
Java Development Kit (JDK) 버전 8 또는 11이 설치되어 있는지 확인하세요.
-
Logstash 다운로드에서 Logstash tarball을 다운로드하세요.
-
터미널에서 다운로드한 폴더로 이동해서 파일의 압축을 풀어요. 사용 중인 Logstash 버전과 플랫폼이 다운로드한 것과 일치하는지 확인하세요:
tar -zxvf logstash-8.8.2-linux-x86_64.tar.gz{% include copy.html %}
-
logstash-8.8.2디렉터리로 이동하세요. -
다음 명령어로 플러그인을 설치하세요:
bin/logstash-plugin install logstash-output-opensearch{% include copy.html %}
다음과 같은 출력이 표시돼요:
Validating logstash-output-opensearch Resolving mixin dependencies Updating mixin dependencies logstash-mixin-ecs_compatibility_support Bundler attempted to update logstash-mixin-ecs_compatibility_support but its version stayed the same Installing logstash-output-opensearch Installation successful
파이프라인 설정은 config 디렉터리에 추가할 수 있어요. Logstash는 플러그인의 데이터를 data 디렉터리에 저장해요. bin 디렉터리에는 Logstash를 시작하고 플러그인을 관리하는 바이너리가 들어 있어요.
Docker
커스텀 Dockerfile로 Logstash 이미지를 빌드하거나 표준 Logstash 이미지를 사용할 수 있어요.
옵션 1: 커스텀 Dockerfile 사용 (권장)
-
필요한 OpenSearch 플러그인이 포함된 Logstash 이미지를 빌드하기 위한 커스텀 Dockerfile을 만드세요:
FROM logstash:<LATEST_VERSION> RUN bin/logstash-plugin install logstash-output-opensearch RUN bin/logstash-plugin install logstash-input-opensearch{% include copy.html %}
-
이미지를 빌드하세요:
docker build -t logstash-with-opensearch-plugins .{% include copy.html %}
옵션 2: 표준 Logstash 이미지 사용
-
Logstash 다운로드에 나온 대로 최신 Logstash 이미지를 pull하세요.
docker pull docker.elastic.co/logstash/logstash:8.8.2{% include copy.html %}
-
Docker 네트워크를 만드세요:
docker network create test{% include copy.html %}
-
이 네트워크로 OpenSearch를 시작하세요:
docker run -p 9200:9200 -p 9600:9600 --name opensearch --net test -e "discovery.type=single-node" opensearchproject/opensearch:1.2.0{% include copy.html %}
-
Logstash를 시작하세요:
docker run -it --rm --name logstash --net test opensearchproject/logstash-oss-with-opensearch-output-plugin:7.16.2 -e 'input { stdin { } } output { opensearch { hosts => ["https://opensearch:9200"] index => "opensearch-logstash-docker-%{+YYYY.MM.dd}" user => "admin" password => "admin" ssl => true ssl_certificate_verification => false } }'{% include copy.html %}
터미널에서 텍스트 처리하기
stdin에서 이벤트를 듣고 stdout으로 이벤트를 출력하는 파이프라인을 정의할 수 있어요. stdin과 stdout은 Logstash를 실행 중인 터미널을 가리켜요.
터미널에 텍스트를 입력하고 출력에서 이벤트 데이터를 확인하려면:
-
-e인자를 사용해서 파이프라인 설정을 Logstash 바이너리에 직접 전달해요. 이 경우stdin이 입력 플러그인이고stdout이 출력 플러그인이에요:bin/logstash -e "input { stdin { } } output { stdout { } }"{% include copy.html %}
더 자세한 출력을 보려면
—debug플래그를 추가하세요. -
터미널에 "hello world"를 입력하세요. Logstash가 텍스트를 처리해서 터미널로 다시 출력해요:
{ "message" => "hello world", "host" => "a483e711a548.ant.amazon.com", "@timestamp" => 2021-05-30T05:15:56.816Z, "@version" => "1" }message필드에는 원본 입력이 들어 있어요.host필드는 Logstash를 로컬에서 실행하지 않을 때 IP 주소예요.@timestamp는 이벤트가 처리된 날짜와 시간을 보여줘요. Logstash는 내부 처리를 위해@version필드를 사용해요. -
Ctrl + C를 눌러서 Logstash를 종료하세요.
문제 해결
이미 실행 중인 Logstash 프로세스가 있으면 오류가 발생해요. 이 문제를 해결하려면:
-
data디렉터리에서.lock파일을 삭제하세요:cd data rm -rf .lock{% include copy.html %}
-
Logstash를 다시 시작하세요.
JSON 또는 HTTP 입력을 처리해서 파일로 출력하기
JSON 요청을 처리하는 파이프라인을 정의하려면:
-
원하는 텍스트 편집기로
config/pipeline.conf파일을 열어요. 파이프라인 설정 파일은 어떤 확장자로 만들어도 되는데,.conf확장자가 Logstash의 관례예요. 입력으로 JSON을 받도록json코덱을 추가하고, 처리된 이벤트를.txt파일로 출력하도록file플러그인을 추가하세요:input { stdin { codec => json } } output { file { path => "output.txt" } }{% include copy.html %}
파일에서 입력을 처리하려면
events-data디렉터리에 입력 파일을 추가하고, 그 경로를 입력의file플러그인에 전달하세요:input { file { path => "events-data/input_data.log" } }{% include copy.html %}
-
Logstash를 시작하세요:
bin/logstash -f config/pipeline.conf{% include copy.html %}
config/pipeline.conf는pipeline.conf파일의 상대 경로예요. 절대 경로를 사용할 수도 있어요. -
터미널에 JSON 객체를 입력하세요:
{ "amount": 10, "quantity": 2}{% include copy.html %}
파이프라인은 한 줄 입력만 처리해요. 여러 줄에 걸친 JSON을 붙여 넣으면 오류가 발생해요.
-
JSON 객체의 필드가
output.txt파일에 추가됐는지 확인하세요:cat output.txt{% include copy.html %}
{ "@version": "1", "@timestamp": "2021-05-30T05:52:52.421Z", "host": "a483e711a548.ant.amazon.com", "amount": 10, "quantity": 2 }입력으로 잘못된 JSON을 넣으면 JSON 파싱 오류가 표시돼요. Logstash는 잘못된 JSON을 버리지 않는데, 그걸로 뭔가를 하고 싶을 수도 있기 때문이에요. 예를 들어 이메일을 발송하거나 Slack 채널에 알림을 보낼 수 있어요.
HTTP 요청을 처리하는 파이프라인을 정의하려면:
-
http플러그인을 사용해서 HTTP를 통해 Logstash로 이벤트를 보내세요:input { http { host => "127.0.0.1" port => 8080 } } output { file { path => "output.txt" } }{% include copy.html %}
옵션을 지정하지 않으면
http플러그인은localhost에 바인딩되고 8080 포트에서 대기해요. -
Logstash를 시작하세요:
bin/logstash -f config/pipeline.conf{% include copy.html %}
-
Postman을 사용해서 HTTP 요청을 보내세요.
Content-Type을application/json값을 가진 HTTP 헤더로 설정하세요:PUT 127.0.0.1:8080 { "amount": 10, "quantity": 2 }{% include copy.html %}
또는
curl명령어를 사용할 수도 있어요:curl -XPUT -H "Content-Type: application/json" -d ' {"amount": 7, "quantity": 3 }' http://localhost:8080 (http://localhost:8080/){% include copy.html %}
입력에
json플러그인을 추가하지 않았는데도 파이프라인 설정이 동작해요. HTTP 플러그인이Content-Type헤더를 기준으로 알맞은 코덱을 자동으로 적용하기 때문이에요. 값을applications/json으로 지정하면 Logstash가 요청 본문을 JSON으로 파싱해요.headers필드에는 Logstash가 받은 HTTP 헤더가 들어 있어요:{ "host": "127.0.0.1", "quantity": "3", "amount": 10, "@timestamp": "2021-05-30T06:05:48.135Z", "headers": { "http_version": "HTTP/1.1", "request_method": "PUT", "http_user_agent": "PostmanRuntime/7.26.8", "connection": "keep-alive", "postman_token": "c6cd29cf-1b37-4420-8db3-9faec66b9e7e", "http_host": "127.0.0.1:8080", "cache_control": "no-cache", "request_path": "/", "content_type": "application/json", "http_accept": "*/*", "content_length": "41", "accept_encoding": "gzip, deflate, br" }, "@version": "1" }
파이프라인 설정 자동 리로드하기
Logstash가 파이프라인 설정 파일이나 입력 로그 파일의 변경 사항을 감지해서 설정을 자동으로 리로드하도록 구성할 수 있어요.
stdin 플러그인은 자동 리로드를 지원하지 않아요.
{: .note }
-
입력 플러그인에 값이
beginning인start_position옵션을 추가하세요:input { file { path => "/Users/<user>/Desktop/logstash7-12.1/events-data/input_file.log" start_position => "beginning" } }{% include copy.html %}
Logstash는 입력 파일에 새로 추가된 이벤트만 처리하고, 재시작할 때 같은 이벤트를 두 번 처리하지 않도록 이미 처리한 이벤트는 무시해요.
Logstash는 진행 상황을
sinceDB파일이라고 불리는 파일에 기록해요. Logstash는 변경 사항을 감시하는 각 파일마다sinceDB파일을 하나씩 만들어요. -
sinceDB파일을 열어서 입력 파일이 얼마나 처리됐는지 확인하세요:cd data/plugins/inputs/file/ ls -al -rw-r--r-- 1 user staff 0 Jun 13 10:50 .sincedb_9e484f2a9e6c0d1bdfe6f23ac107ffc5 cat .sincedb_9e484f2a9e6c0d1bdfe6f23ac107ffc5 51575938 1 4 7727{% include copy.html %}
sinceDB파일의 마지막 숫자(7727)는 마지막으로 처리된 것으로 확인된 이벤트의 바이트 오프셋이에요. -
입력 파일을 처음부터 처리하려면
sinceDB파일을 삭제하세요:rm .sincedb_*{% include copy.html %}
-
—-config.reload.automatic인자를 붙여서 Logstash를 시작하세요:bin/logstash -f config/pipeline.conf --config.reload.automatic{% include copy.html %}
reload옵션은 파이프라인 설정 파일 끝에 새 줄을 추가했을 때만 리로드해요.샘플 출력:
{ "message" => "216.243.171.38 - - [20/Sep/2017:19:11:52 +0200] \"GET /products/view/123 HTTP/1.1\" 200 12798 \"https://codingexplained.com/products\" \"Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)\"", "@version" => "1", "host" => "a483e711a548.ant.amazon.com", "path" => "/Users/kumarjao/Desktop/odfe1/logstash-7.12.1/events-data/input_file.log", "@timestamp" => 2021-06-13T18:03:30.423Z } { "message" => "91.59.108.75 - - [20/Sep/2017:20:11:43 +0200] \"GET /js/main.js HTTP/1.1\" 200 588 \"https://codingexplained.com/products/view/863\" \"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0\"", "@version" => "1", "host" => "a483e711a548.ant.amazon.com", "path" => "/Users/kumarjao/Desktop/odfe1/logstash-7.12.1/events-data/input_file.log", "@timestamp" => 2021-06-13T18:03:30.424Z } -
입력 파일에 새 줄을 추가하세요.
- Logstash가 변경 사항을 즉시 감지하고 새 줄을 이벤트로 처리해요.
-
pipeline.conf파일을 변경하세요.- Logstash가 변경 사항을 즉시 감지하고 수정된 파이프라인을 리로드해요.