Logstash - 기본

Sungjin·2022년 12월 13일
0

ELK Stack

목록 보기
2/4

엘라스틱 스택 구성요소 중 로그스태시에 대해 알아보자. 로그스태시는 영어 단어 그대로 해석하면 로그를 저장한다라는 의미이다. 컴퓨터 시스템에서 로그란 시스템에서 일련의 동작 과정을 기록하는 것으로 로그는 성능, 오류, 동작 과정 등의 중요한 정보를 담고 있다. 운영 과정에서 문제 해결을 위해 반드시 필요하며 개발 과정에서도 테스트나 디버깅을 위해 필요한 정보이다.

로그활용은 간단하지만은 않다. 로그 형태가 표준화되어 있지 않기 때문에 로그 생산자는 제각각 다양한 방법으로 로그를 생성하고 있다. 또한, 로그는 반정형이며 세상의 모든 것이 로그가 될 수 있기 때문에 로그 형태를 강제할 방법도 없다. 결국, 로그를 수집하는 쪽에서 로그 형태를 분석하고 시스템에서 인식할 수 있도록 로그를 정제하는 작업이 필요한데, 로그스태시는 이 과정을 쉽고 편하게 할 수 있도록 지원한다. 어떤 형태의 로그에 대해서도 로그를 수집 - 가공 - 전송하는 일련의 과정을 간편하게 구현하기 위한 강력한 기능까지 제공한다.

이번에는 로그스태시에서 파이프라인을 통해 데이터를 수집하고 원하는 형태로 가공하는 방법을 익히고 엘라스틱 스택에서 로그를 쉽게 모니터링하는 방법에 대해서 배워보자.

🌈 로그스태시 소개

로그스태시는 플러그인 기반의 오픈소스 데이터 처리 파이프라인 도구다. 다소 복잡하고 귀찮은 데이터 전처리 과정을 별도의 애플리케이션 작성 없이 비교적 간단한 설정만으로 수행할 수 있다.

로그스태시는 비츠를 포함한 여러 소스 파일을 입력으로 받을 수 있고 데이터를 수정/삭제/추가해 엘라스틱서치나 다른 시스템으로 데이터를 전송할 수 있다.

🔎 로그스태시 특징

로그스태시의 특징은 플러그인 기반으로 확장성이 뛰어나고 현업에서 사용하는 대부분의 데이터 소스를 지원하고 있다. 성능이나 안정성 또한 뛰어나다.

  • 플러그인 기반 : 로그스태시의 파이프라인을 구성하는 각 요소들은 전부 플러그인 형태로 만들어져 있다.

  • 모든 형태의 데이터 처리 : 기본 제공되는 플러그인들의 조합만으로도 대다수의 데이터 소스에서 JSON, XML 등의 구조화된 텍스트뿐만 아니라 다양한 형태의 데이터를 입력받아 가공한 다음에 저장할 수 있다.

  • 성능 : 자체적으로 내장되어 있는 메모리와 파일 기반의 큐를 사용하므로 처리 속도와 안정성이 높다.

  • 안정성 : 엘라스틱서치의 장애 상황에 대응하기 위한 재시도 로직이나 오류가 발생한 도큐먼트르 따로 보관하는 데드 레터큐를 내장하고 있다. 파일 기반의 큐를 사용할 경우 뜻하지 않은 로그스태시의 장애 상황에서도 도큐먼트 유실을 최소화할 수 있다.

🌈 파이프라인
로그스태시의 가장 중요한 부분은 파이프라인이다. 파이프라인은 데이터 입력받아 실시간으로 변경하고 이를 다른 시스템에 전달하는 역할을 하는 로그스태시의 핵심 기능이다.

파이프라인은 입력, 필터, 출력이라는 세 가지 구성요소로 이뤄진다. input, output 은 필수 구성 요소이고, filter 는 옵션이다.

그렇다면, 표준 입력을 받아서 표준 출력에 보여주는 간단한 예제를 실행해보자.

먼저, 로그스태시가 설치된 위치로 이동하여야한다.

./bin/logstash -e "input {stdin{}} output {stdout{}}"

일반적으로 파이프라인은 따로 설정 파일을 만들어서 기록하거나 config 폴더의 pipelines.yml에 기록하는데, -e 옵션을 사용하면 콘솔에서 직접 파이프라인을 설정할 수 있다.

로그스태시는 JSON 형태로 데이터를 출력하는데, @version 이나 @timestamp는 로그스태시가 만든 필드로 혹시 사용자가 만든 필드와 충돌이 날 것을 대비해 @ 기호가 붙어 있다. message, host 필드는 데이터와 시스템 사용자를 나타낸다. 여기에는 @ 기호가 붙지 않았는데, @ 기호는 로그스태시에 의해 생성된 필드, 붙지 않은 필드는 수집을 통해 얻어진 정보라고 생각하면 된다.

간단한 파이프라인일 경우 콘솔에서 직접 작성할 수 있지만 작업의 이력 관리를 위해 piplines.yml 이나 파이프라인 설정 파일을 만들어 로그스태시를 동작하는 것이 좋다. 기본 템플릿은 다음과 같다.

input {
  { 입력 플러그인 }
}

filter {
  { 필터 플러그인 }
}

output {
  { 출력 플러그인 }
}

🔎 입력

파이프라인의 가장 앞부분에 위치하며 소스 원본으로부터 데이터를 입력받는 단계다. 직접 대상에 접근해 읽어 들이는 경우도 있지만 서버를 열어놓고 받아들이는 형태의 구성도 가능하다.

로그스태시는 다양한 형태의 데이터를 인식할 수 있고 이를 쉽게 처리하기 위해 다양한 입력 플러그인을 통해 가져올 수 있다. 다음은 자주 사용하는 입력 플러그인이다.

입력 플러그인설명
file리눅스의 tail -f 명령처럼 파일을 스트리밍하여 이벤트를 읽어드린다.
syslog네트워크를 통해 전달되는 시스로그를 수신한다.
kafka카프카의 토픽에서 데이터를 읽어 들인다.
jdbcJDBC 드라이버로 지정한 일정마다 쿼리를 실행해 결과를 읽어드린다.

지금 부터는 파일 플러그인을 통한 입력을 알아보자. 로그스태시의 플러그인 대부분은 사용법이나 형태가 비슷하므로 파일 플러그인 사용법을 배워두면 다른 입력 플러그인 사용도 크게 어렵지 않을 것이다. 그럼 이제 로그스태시가 설치된 config 폴더에 설정파일을 만들고 파일 입력 플러그인을 적용해보자.

파일 플러그인에는 여러가지 옵션이 있는데, 그중 path 는 읽어들일 파일 위치를 경정한다. logstash-test.log파일을 읽는 것으로 설정했는데, 실시간으로 파일의 변경을 감지해 읽어 들인다.

start_position 은 최초 파일을 발견했을 때 파일을 읽을 위치로, 파일의 시작 부분부터 읽어 들일지 끝부분부터 새로운 라인만 읽어들일 지 결정할 수 있다.

출력은 표준 출력 플러그인을 사용했기 때문에 입력이 발생하면 모니터에 출력한다.

실시간으로 출력되는 logstash-test.log 를 수집하기 위해 로그스태시를 실행해보자.

./bin/logstash -f ./libexec/config/logstash-test.conf

먼저 log 파일에 “Hello World” 를 입력해보자.

config 폴더에서 명시한 파일의 패스에서 입력된 message를 출력하는 것을 볼 수 있다. 일단은 message에 적힌 구문을 분석해 의미 있는 데이터로 변환하는 역할을 필터 플로그인이 해야 하며 이는 로그스태시의 가장 중요한 업무라 보면 된다.

🔎 필터

입력 플러그인이 받은 데이터를 의미 있는 데이터로 구조화하는 역할을 한다. 필수 구성요소가 아니어서 필터 없이 파이프라인을 구성할 수 있지만, 필터 없는 파이프라인은 그 기능을 온전히 발휘하기 어렵다.

로그스태시 필터는 비정형 데이터를 정형화하고 데이터 분석을 위한 구조를 잡아준다. 필터 역시 플러그인 형태이며, 입력과 비슷하게 다양한 필터 플러그인이 존재한다. 다음은 자주 사용되는 필터들의 목록이다.

필터 플러그인설명
grokgrok 패턴을 사용해 메시지를 구조화된 형태로 분석한다. grok 패턴은 일반적인 정규식과 유사하나, 추가적으로 미리 정의된 패턴이나 필드 이름 설정, 데이터 타입 정의 등을 도와준다.
dissect간단한 패턴을 사용해 메시지를 구조화된 형태로 분석한다. 정규식을 사용하지 않아 grok에 비해 자유도는 조금 떨어지지만 더 빠른 처리가 가능하다.
mutate필드명을 변경하거나 문자열 처리 등 일반적인 가공 함수들을 제공한다.
date문자열을 지정한 패턴의 날짜형으로 분석한다.

예제를 진행하기 위해 파일을 하나 만들어 보자.

filter-test.log라는 이름으로 다음과 같은 예제 로그들을 직접 텍스트로 입력하였다.

이제 앞서 작성했던 logstash-test.conf 를 수정해보자.

./bin/logstash -f ./libexec/config/logstash-test.conf

파일 플러그인에 sincedb_path 라는 옵션이 추가되었다. 이 옵션은 파일을 어디까지 읽었는지 기록하는 파일이다. start_position 의 기능을 봤을 때 beginning 은 처음부터, end 는 끝에서부터 파일을 읽는 것이라고 했다. 하지만, 이와 같은 기능들은 파일을 불러들이는 최초에 한 번만 적용된다는 점이다. 즉, 파일에 이미 로그가 존재했을 때 로그스태시를 시동을 걸면 존재하는 로그들을 다 읽어들이지만 그 다음부터 시동을 걸면 sincedb_path 로 인해 어디까지 읽었는지 기록이 되어서 이미 읽었던 로그들은 읽지 않게 된다.

sincedb_path를 따로 입력하지 않으면 /data/plugins/inputs/file의 위치에 자동으로 생성이 되고, /dev/null 로 지정했을 시에는 따로 생성을 하지 않기 때문에 시동을 걸 때마다 파일을 처음부터 읽을 수 있게 된다.

💡 문자열 자르기

데이터나 로그는 대부분 길이가 길기 때문에 우리가 원하는 형태로 분리해야 한다.

먼저 filter 플러그인을 추가해보자.

mutate 플러그인은 필드를 변형하는 다양한 기능들을 제공하고 있다. 필드 이름을 바꾸거나 변경하거나 삭제하는 작업 등을 할 수 있다. mutate 는 플러그인 내부에 옵션이 다양한다 split 도 여러 옵션 중하나다.

다음은 자주 사용하는 옵션들이다.

mutate 옵션설명
split구분 문자를 기준으로 문자열을 배열로 나눈다.
rename필드 이름을 바꾼다.
replace해당 필드 값을 특정 값으로 바꾼다.
uppercase문자를 대문자로 바꾼다.
lowercase문자를 소문자로 바꾼다.
join배열을 구분 문자로 연결해 하나의 문자열로 합친다.
gsub정규식이 일치하는 항목을 다른 문자열로 대체한다.
merge특정 필드를 다른 필드에 포함시킨다.
coercenull인 필드값에 기본값을 넣어준다.
strip필드 값의 좌우 공백을 제거한다.

많은 옵션들이 있기에 순서가 중요하다.

coerce - rename - update - replace - convert - gsub - uppercase - capitalize - lowercase - strip - join - merge - copy 순으로 옵션이 부여된다.

이제 로그스태시를 실행시켜 보자.

message 필드 문자열이 공백을 기준으로 구분되어 배열 형태의 데이터가 되었다. 구분 문자들은 ‘필드명[숫자]’ 와 같이 접근할 수 있다. 예를 들어, ID를 가리키는 필드는 message[2] 와 같다. mutate 는 많이 사용하는 대표적인 필터 플러그인인데 다른 옵션들도 사용해보자.

add_field 는 필드를 새로 만들어서 추가하는 옵션이다. id 라는 필드를 새로 생성하고 앞에서 split으로 분리되어 있는 message 필드의 배열 중에서 message[2]의 데이터를 넣는다.

remove_field는 특정 필드를 삭제하는 옵션이다. 이와 같은 옵션들은 mutate 의 특별한 옵션은 아니고 모든 필터 플러그인에서 사용할 수 있는 옵션이다.

다음은 모든 필터에서 사용되는 대중적인 옵션들이다.

공통 옵션설명
add_field새로운 필드를 추가할 수 있다.
add_tag성공한 이벤트에 태그를 추가할 수 있다.
enable_metric메트릭 로깅을 활성화하거나 비활성화 할 수 있다. 기본적으로 활성화되어 있으며, 수집된 데이터는 로그스태시 모니터링에서 해당 필터의 성능을 분석할 때 사용된다.
id플러그인의 아이디를 설정한다. 모니터링 시 아이디를 이용해 특정 플러그인을 쉽게 찾을 수 있다.
remove_field필드를 삭제할 수 있다.
remove_tag성공한 이벤트에 붙은 태그를 제거할 수 있다.

이제, 로그스태시를 실행해보자.

필터 플러그인은 순서대로 동작하는데 먼저 split 에 의해 message 필드의 문자열이 공백 기준으로 분리 되었다. 다음으로 id 필드를 추가하고 필드값은 message[2]를 사용한다. 마지막으로 message 필드가 사라진다.

참고로, split 이라는 필터 플러그인이 있는데 단일 문서를 복수의 문서를 나눠주는 역할을 한다. 지금 사용한 플러그인은 mutate 의 플러그인이다.

💡 dissect 를 이용한 문자열 파싱

이번에는 dissect 플러그인을 이용해 문자열을 파싱해보자. 앞에서 mutate 플러그인의 split 옵션을 이용해 문자열을 분리했지만 하나의 구분자만 이용해서 데이터를 나눠야 한다는 단점이 있다. dissect 플러그인은 패턴을 이용해 문자열을 분석하고 주요 정보를 필드로 추출하는 기능을 수행한다.

logstash-test.conf 파일의 filter 부분을 수정해보자.

dissect 플러그인의 mapping 옵션에 구분자 형태를 정의하고 필드를 구분한다. %{필드명}으로 작성하면 중괄호안의 필드명으로 새로운 필드가 문들어진다. %{} 외의 문자들은 모두 구분자 역할을 한다.

현재, 설정한 필드 구분자와 테스트할 로그의 형태를 표현해보자. (^ 는 공백을 표시한다)

  • dissect

    	- `[%{timestamp}]^[%{id}]^[%ip}^%{port}^[%{level}] - %{message}.`
  • log1

    	- `[2020-01-02 14:17]^[ID1]^127.0.0.1^9500^[INFO] - connected.`
  • log2

    	- `[2020/01/02 14:19:25]^^^[ID2]^127.0.0.1^1070^[warn] - busy server.`

로그스태시를 실행해보도록 하자.

두 번째 로그에서 오류가 발생한 것을 볼 수 있다. 문제 발생의 이유를 알아보자.

dissect 플러그인의 매핑 패턴은 [timestamp] 와 [id] 간의 공백이 하나이다. 하지만, 두번 째로그는 공백이 세 칸이기 때문에 매핑에서 정해놓은 구분자가 아니라며 오류를 발생시킨다.

이를 해결하기 위해 다른 매핑 정보를 입력해보도록 하자.

먼저, -> 기호는 공백을 무시한다.%{필드명 -> } 을 입력하면 공백이 몇 칸이든 하나의 공백으로 인식한다. 그리고 %{?필드명} 혹은 %{}를 입력하면 그 필드명은 결과에 포함되지 않는다. 그래서 %{?->} 라고 입력하면 공백을 하나의 필드로 만든 다음 무시하게 된다. 기존 level 이나 message 필드도 모두 무시하게 된다. %{+필드명} 을 작성하면 여러 개의 필드를 하나의 필드로 합쳐셔 표현한다.

이제, 결과를 확인해 보자.

오류가 더 이상 발생하지 않았고, ip 와 port는 ip라는 하나의 필드로 변경되었고, level 과 message 필드는 결과에 포함되지 않게 된다.

💡 grok를 이용한 문자열 파싱

grok는 정규 표현식을 이용해 문자열을 파싱할 수 있다. 정규 표현식은 특정한 규칙을 갖는 문자열을 표현하는 언어이다. grok는 자주 사용하는 정규 표현식들을 패턴화해뒀으며 패턴을 이용해 %{패턴:필드명} 형태로 데이터에서 특정 필드를 파싱할 수 있다. 다음은 grok에서 지원하는 패턴들이다.

패턴명설명
NUMBER십진수를 인식한다. 부호와 소수점을 포함할 수 있다.
SPACE스페이스, 탭 등 하나 이상의 공백을 인식한다.
URIURI를 인식한다. 프로토콜, 인증 정보, 호스트, 경로, 파라미터를 포함할 수 있다.
IPIP 주소를 인식한다. IPv4 와 IPv6 모두 인식 가능하다.
SYSLOGBASE시스로그의 일반적인 포맷에서 타임스탬프, 중요도, 호스트, 경로, 파라미터를 포함할 수 있다.
TIMESTAMP_ISO8601ISO8601 포맷의 타임스탬프를 인식한다. 2020-01-01T12:00:00+09:00 과 같은 형태이며, 타임존까지 정확한 정보를 기록하고 로그에선 많이 쓰이는 날짜 포맷이기에 grok 표현식을 작성할 때도 유용하다.
DATA이 패턴의 직전 패턴부터 다음 패턴 사이를 모두 인식한다. 특별히 인식하고자 하는 값의 유형을 신경 쓸 필요가 없으므로 특별히 값이 검증될 필요가 없다면 가장 많이 쓰이는 패턴 중 하나이다.
GREEDYDATADATA 타입과 동일하나, 표현식의 가장 뒤에 위치시킬 경우 해당 위치부터 이벤트의 끝까지를 값으로 인식한다.

사람들이 자주 쓰는 패턴들은 이미 만들어져 있기 때문에 가져다가 사용하면 되고, 원하는 패턴이 없는 경우 패턴을 직접 만들어 사용할 수 있다.

이제, logstash-test.conf를 수정해 보자.

TIMESTAMP_ISO8601 은 ISO8601 표준 시간 표기법에 대한 패턴이다. DATA 는 모든 데이터를 인식하고, IP 는 IPv4 형태의 데이터를 인식한다. NUMBER 는 숫자를 인식하는데, 변수명 뒤에 :int 를 추가하면 변경시 정수 타입으로 지정한다. LOGLEVEL 은 시스로그 레벨을 인식한다. 특수 문자와 같은 경우는 (백슬래시)를 통해 이스케이프할 수 있다. []* 라는 정규식을 이용해 모든 공백을 허용하게 할 수 있다.

이제 로그스태시를 실행해 보자.

보이는 것과 같이 첫번 째 로그는 원하는 형태로 필드가 구분되었다. 하지만 두 번째는 오류가 뜬다. 이와 같은 이유는 현재 날짜 포맷이 맞지 않기 때문이다.

날짜/시간 데이터 포맷은 로그 만드는 사용자가 너무나 다양한 형태로 포맷을 만들어서 사용하기 때문에 데이터를 수집하는 쪽에서 반드시 포맷을 통일해줘야 한다.

TIMESTAMP_ISO8601 은 다음과 같은 포맷이다.

TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?

연-월-일 형태의 포맷만 지원하고 있는데 연/원/일 형태의 포맷도 지원되도록 수정해보자. 사용자가 패턴을 지정하기 위해서는 grok의 pattern-definitions 옵션을 사용한다.

이제, logstash-test.conf 파일을 수정해보도록 하자.

모두 정상적인 결과가 나온 것을 확인할 수 있다. dissectgrok 플러그인은 패턴을 이용해 구문 분석을 한다는 공통점이 있지만 성능 차이가 있다. 로그형식이 일정하고 패턴이 변하지 않는다면 dissect 를 사용하는 것이 좋다. 패턴을 해석하지 않아서 속도가 빠르기 때문이다. 하지만 로그 형태가 일정하다고 장담하기 힘들다면 예외 처리나 패턴이 자유로운 grok 을 사용하는 것이 좋다.

dissect 로 해석 가능한 것이라면 무조건적으로 성능이 더 좋다라는 것을 알아두면 된다.

💡 대소문자 변경

소문자를 대문자로 바꿔보면서 필터 플러그인을 통해 얼마나 쉽게 데이터를 가공할 수 있는지 알아보자.

먼저, logstash-test.conf 파일을 수정해 보자.

level 필드의 데이터가 모두 대문자로 바뀐 것을 확인할 수 있다. 소문자로 바꾸고 싶은 경우는 lowercase 를 사용하면 된다.

💡 날짜/시간 문자열 분석

이벤트가 발생한 날짜/시간 정보는 모니터링이나 진단을 하는 데 없어서는 안되는 매우 중요한 정보다. 하지만 로그 생성자들이 만드는 날짜/시간 포맷이 통일되어 있지 않다는 문제가 있다. ISO8601 같은 표준 표기법이 있지만 국가나 문화권별로 표현하는 방법이 다르고 강제적인 규약이 없으니 로그를 생성하는 곳마다 다른 날짜/시간 포맷을 사용한다. 예를 들어 시간의 경우 ‘5시 47분’, ‘5:47’, ‘PM 5:47’ 같이 다양하게 표현이 가능하다. 이런 다양한 포맷을 date 플러그인을 이용해 기본 날짜/시간 포맷으로 인덱싱할 수 있다. 엘라스틱서치의 경우 ISO8601 표준 포맷을 기본적으로 사용하고 있다.

logstash-test.conf 를 수정하여 date 플러그인을 사용해보도록 하자.

mutatestrip 은 필드의 양 옆에 공백이 있을 경우 제거한다. date 플러그인은 날짜/시간 관련된 데이터를 ISO8601 타입으로 일괄적으로 변경한다. match 옵션의 첫 번째 값은 매칭할 필드명이고 이후 값들은 매칭할 날짜/시간 포맷이다.

즉, timestamp 필드 중에서 YYYY-MM-DD HH:mm 포맷이거나 yyyy/MM/dd HH:mm:ss 포맷인 경우 매칭된다. targetmatch 에 의해 매칭된 필드가 저장될 새로운 필드를 의미하고, timezone은 원본 문자열에 타임존 정보가 포함되어 있지 않을 때 어떤 타임존으로 분석할 지 설정할 수 있다. 로그스태시는 타임존을 지정하지 않을 경우 로컬 PC의 타임존을 적용하게 된다.

로그스태시에서 사용하는 날짜/시간 포맷은 Joda Time 라이브러리 포맷을 사용한다.

기호의미
Y/y연도
M
m
D일(연 기준)
d일(월 기준)
H시(0 ~ 23)
h시(0 ~ 12)
S밀리초(0 ~ 999)
s초(0 ~ 59)

이제 로그스태시를 실행해 보자.

new_timestamp 라는 새로운 필드가 생성되었고, 시간 포맷이 달랐던 두 데이터가 ISO8601 타입의 포맷으로 통일되는 것을 확인할 수 있다.

💡 조건문

필터는 기본적으로 모든 이벤트에 적용된다. 단순히 csv나 json과 같이 정해진 포맷을 읽어 들이는 경우라면 모르겠지만, 일반적으로 입력되는 이벤트의 형태는 다양하고 이에 따라 각기 다른 필터를 적용해야 한다. 로그스태시에서는 일반적인 프로그래밍 언어와 동일한 형태로 if, else if, else 조건문을 제공하며, 이를 이용해 이벤트마다 적절한 필터를 적용할 수 있다.

logstash-test.conf 파일에 조건문을 추가해보자.

if 조건문을 통해 필드명이 특정 조건과 일피하는지 확인 하는데, level 은 앞서 grok 을 통해 만들어진 필드다. 파이프라인은 순서대로 동작하기 때문에 앞에서 level 필드가 만들어져야만 사용할 수 있다. drop 은 데이터를 삭제하는 플러그인이다.

조건문에서 정의한 것 처럼, “INFO” 였던 로그는 출력되지 않고 “WARN” 였던 로그는 remove_field 가 된 것을 확인할 수 있다.

🔎 출력

출력은 파이프라인의 입력과 필터를 거쳐 가공된 데이터를 지정한 대상으로 내보내는 단계다. 파이프라인의 마지막 단계이며 입력, 필터 플러그인과 마찬가지로 다양한 출력 플러그인을 지원한다.

자주 사용하는 출력 플러그인은 다음과 같다.

|출력 플러그인|설명|
|elasticsearch|가장 많이 사용되는 출력 플러그인으로, bulk API를 사용해 엘라스틱서치에 인덱싱을 수행한다.|
|file|지정한 파일의 새로운 줄에 데이터를 기록한다.|
|kafka|카프카 토픽에 데이터를 기록한다.|

출력 플러그인 예제를 작성해보자. logstash-test.conf를 다음과 같이 수정하자. 참고로, 결과를 엘라스틱서치로 전송할 것이므로 엘라스틱서치를 먼저 실행해놓아야 한다.

두개의 출력 플러그인을 추가했다. 하나는 파일 플러그인으로 데이터를 파일 형식으로 전송한다. path 옵션에 저장할 위치를 적어주면 된다.

두 번째 플러그인은 엘라스틱 서치 플러그인으로 데이터를 엘라스틱 서치에 전송한다. 인덱스명을 설정할 수 있고 호스트 URL 이나 라우팅 같은 다양한 옵션을 사용할 수 있다.

다음은 엘라스틱서치 플러그인 옵션이다.

옵션설명
hosts이벤트를 전송할 엘라스틱서치의 주소
index이벤트를 인덱싱할 대상 인덱스
document_id인덱싱될 문서의 아이디를 직접 지정할 수 있는 옵션
user/password엘라스틱서치에 보안 기능이 활성화되어 있을 때 인증을 위한 사용자 이름과 비밀번호
pipeline엘라스틱서치에 등록된 인제스트 파이프라인을 활용하기 위한 옵션
template로그스태시에서 기본 제공되는 인덱스 템플릿 외에 커스텀 템플릿을 사용하기 위한 옵션. template에는 정의한 인덱스 템플릿 파일의 경로를, template_name 에는 엘라스틱서치에서 어떤 이름으로 등록할지를 설정할 수있다.
template_name

이제 결과를 확인해보자. 물론, 엘라스틱서치에도 로그가 출력이 되니 먼저 엘라스틱서치가 가동 중이어야 한다.

먼저, 엘라스틱서치의 인덱스에 접근해보도록하자.

GET output/_search

엘라스틱서치에 output이라는 인덱스란 이름으로 잘 출력이 된 것을 확인해볼 수 있다.

이제, 파일에 잘 출력되었는지를 확인해보자. 파일이 출력되는 경로를 가서 cat 명령을 날려보자.

cat filter.json

파일 또한 잘 출력된 것을 확인할 수 있다.

🔎 코덱

코덱은 입력/ 출력/ 필터와 달리 독립적으로 동작하지 않고 입력과 출력 과정에 사용되는 플러그인이다. 입/ 출력시 메시지를 적절한 형태로 변환하는 스트림 필터다.

자주 사용하는 플러그인은 다음과 같다.

플러그인설명
json입력시 json 형태의 메시지를 객체로 읽어 들인다. 출력시에는 이벤트 객체를 다시금 json 형태로 변환한다.
plain메시지를 단순 문자열로 읽어 들인다. 출력 시에는 원하는 포맷을 지정할 수 있다.
rubydebug로그스태시의 설정을 테스하거나 예기치 못한 파이프라인 설정 오류를 디버깅하기 위한 목적으로 주로 사용되며, 출력시 루비 언어의 형태로 이벤트를 기록한다. 입력시에는 사용되지 않는다.

간단히 사용법을 익혀보자. 다음과 같이 logstash-test.conf를 수정해보도록 하자.

실행해보자.

다음과 같은 오류가 발생한다. 코덱을 잘못 사용하고 있다는 것이다. 표면상으로는 JSON 문법이 잘못되었다는 뜻이지만 결국 파일을 인코딩 하지 못한 것이다. 입력 파일은 플레인 텍스트 형식인데 JSON 형태로 인코딩을 하려고 했기 때문이다. 다시한번 적당한 코덱으로 바꾸어 보자.

CSV 파일의 경우 코덱 플러그인으로 plain 을 사용하면 제대로 동작하는데, plain 코덱의 경우 굳이 명시하지 않아도 기본 적용된다. 로그스태시를 실행하면 기본 결과와 동일하기 때문에 넘어가도록 하자.

이 외에 입력 코덱은 multiline 코덱도 많이 사용한다. multiline 코덱은 여러 라인 형태로 들어오는 로그를 하나의 로그로 만들기 위해 사용한다. 하나의 로그가 여러 줄로 작성되어 있는 경우 꼭 필요한 플러그인이다.

이제, 출력 코덱을 확인해보자. 입력 코덱과 사용법은 같으며, 데이터를 디코딩하는 역할을 한다. 먼저, logstash-test.conf 를 수정해보도록 하자.

주석을 하나씩 풀면서 실행을 해보도록 하자.

  • json
  • line
  • rubydebug

표준 출력 플러그인에서 코덱을 따로 명시하지 않으면 기본으로 사용되는 코덱이다.

이렇게 코덱에 따라 같은 데이터라도 출력 형태가 달라지는 것을 확인할 수 있다.

🌈 다중 파이프라인

이번에는 하나의 로그스태시에서 여러 개의 파이프라인을 동작하는 방법을 알아보자. 프로젝트를 진행하다 보면 로그 입수 경로가 다양해진다. 서버가 다양할 수도 있고 다양한 형태의 로그도 있을 수도 있다.

기존에는 로그스태시를 여러 개 실행했다. 하지만 이런 문제는 문제가 있다. 실행된 로그스태시는 개별적이고 독립적인 JVM 인스턴스이기 때문에 모니터링이 어렵고 전체적인 관리가 어려워 좋은 방법이 아니다. 다른 방법으로는 하나의 로그스태시에 조건문을 두어 분리하는 것이었다. 이렇게 하면 하나의 파이프라인으로 처리할 수 는 있지만 필터 처리가 복잡해진다.

🔎 다중 파이프라인 작성

다중 파이프라인은 하나의 로그스태시에서 여러 개의 파이프라인을 독립적으로 실행할 수 있게한다. 다중 파이프라인을 실행하는 방법을 배워 보자.

먼저 pipelines.yml 을 수정해야한다. 이 파일은 config 폴더에서 찾을 수 있다.

이 부분을 참고하여 수정하면 된다. 다음과 같은 내용을 추가하자.

mypipe1 과 mypipe2 2개의 파이프라인을 정의한다. 다음은 많이 쓰는 파이프라인 설정이다

설정설명
pipeline.id파이프라인의 고유한 아이디
path.config파이프라인 설정 파일의 위치
pipeline.batch.size입력시 하나의 워커당 최대 몇 개까지의 이벤트를 동시에 처리할지를 결정한다. 배치 처리된 이벤트들은 엘라스틱서치 출력에서 하나의 요청으로 묶이기 때문에, 이 수치가 클수록 요청 수행 횟수가 줄어들어 인덱싱 성능 개선 효과가 있지만, 그만큼 단일 요청이 커지므로 적절히 조절해가며 튜닝해야한다.
queue.type파이프라인에서 사용할 큐의 종류를 정할 수 있다. 기본적으로 memory 타입이 사용되나, persisted 타입을 선택해 이벤트의 유실을 좀 더 최소화할 수 있다.

이제 mypipe1.conf 와 mypipe2.conf 를 생성해보자.

  • mypipe1.conf
  • mypipe2.conf

두 개의 파이프라인을 작성하였다. 이제 로그스태시를 실행해보자. 로그스태시를 실행하면 기본적으로 pipelines.yml 에 정의되어 있는 파이프라인을 인식하는데 -f, -e 옵션을 사용해 실행하면 pipelines.yml 대신 사용자가 지정한 파이프라인을 사용하게 된다.

파이프 라인이 잘 적용되었는지 확인하기 위해 multi-pipe1, multi-pipe2 에 각각 “Hello World”를 저장해보자.

  • stdout
  • elasticsearch

GET multi-pipe2/_search

로그스태시를 통해 다중파이프라인이 잘 적용된 것을 확인할 수 있다.

profile
WEB STUDY & etc.. HELLO!

0개의 댓글