출처: https://evilimp79.wordpress.com/2014/10/23/logstash-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/
logstash
logstash 설치와 설정
기본적으로는 사이트에서 다운로드를 받고 bin/logstash를 실행시키면 됨.
command line의 입력에 대한 로그를 처리하는것은 다음과 같이 수행한다.
1 |
bin/logstash -e 'input { stdin { } } output { stdout {} }' |
만약 파일을 이용한 설정을 하기위해서는 .conf 파일을 직접 작성하여야 하며 해당 conf 파일을 이용하여 logstash를 실행시키기 위해서는 다음과 같이 실행한다.
1 |
bin/logstash agent -f logstash.conf |
conf
conf 파일의 구성
conf 파일은 기본적으로 input, filter, output 의 3가지 요소로 구성된다.
input은 logstash가 로그를 수집할 대상에 대한 정보를 설정한다.
filter는 로그에 대한 분해(parsing)를 지원하기 위한 설정들을 한다.
output은 수집된 로그를 적재/노출 할 대상에 대한 정보를 설정한다.
추가적으로 설정할 수 있는 것은 codec이라는 것인데, 이는 input, output 등에서 사용될 데이터에 대한 형식을 의미한다. 예를 들어 일반적인 메시지수준이라면 plain이고 json과 같은 형식을 사용할 수 도 있다.
input
input에서는 데이터를 수집할 대상에 대한 정의를 해주는데, logstash가 기본적으로 제공해주는 대상은 약 40여가지 된다. 쉽게 살펴볼 수 있는 apache accesslog 나 log4j에서 발생되는 로그를 수집하기 위해서는 일반적으로 file, tcp 등을 이용하여 데이터를 수집한다. log4j의 경우 별도의 input 설정을 통해 log4j에서 바로 logstash로 전달 할 수도 있다. 각각의 간단한 input 설정 예제는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 |
input { file { # path는 대상 파일의 절대경로를 작성(accesslog 나 exception log 파일 위치) path => "/Users/evilimp/Dev/elk/logs/square.log" # type은 대상 데이터들에게 붙여주는 일종의 alias와 같다. elasticsearch에 저장하는 경우 type이 별도의 항목으로 저장된다. type => "square" } tcp { # tcp 통신에 대해 수집할 대상 서버의 host 정보 host => "localhost" # tcp로 확인할 port 정보. port는 mode라는 설정 항목에 따라서 의미가 변하는데 mode가 server인 경우 데이터가 들어오기를 기다리고 있는(리스닝) port를 의미하고, mode가 client인 경우에는 데이터를 수집할 port를 의미한다. port => 3333 # 추가 필드 정의 add_field => { "server" => "square" } type => "tomcat" } log4j { # log4j는 기본적으로 SocketAppender를 이용하여 발생되는 로그를 socket 통신으로 타서버로 전송해주는 것을 전제한다. 물론 대상 서버가 localhost여도 된다. # 대상 서버 host 정보 host => "localhost" # log4j 로 확인할 port 정보. port => 4560 type => "log4j" } } |
만약 accesslog 와 log4j를 동시에 수집하는 경우에는 type에 따라서 분리를 하여 향후 분석에서 구분할 수 있고, output에서도 type에 따른 다른 대상이나 처리 방법을 정의할 수 있다.
output
input으로부터 수집된 데이터를 적재 또는 전송하기 위한 정의해주는데, input과 마찬가지로 logstash가 이미 60여가지의 대상을 지원해주기 때문에 생각하는 대상이 있다면 먼저 ㅣogstash가 지원해주는지를 확인하는 것이 필요하다. 샘플로 콘솔에 데이터를 출력하면서 elasticsearch에 데이터를 적재하는 설정을 확인해보면 다음과 같다. 더 많은 설정 항목이 있지만 로컬에 기본으로 설치한 elasticsearch의 경우에는 host만 지정해주어도 데이터가 적재된다.(이는 logstash와 elasticsearch가 json으로 통신하기 떄문에 해당 json 형태대로 elasticsearch에 자동으로 인덱싱(logstash-{YYYY.MM.DD)된다.)
1
2
3
4
5
6
7 |
output { stdout{} # 콘솔에 바로 출력 elasticsearch { # elasticsearch가 구동되고 있는 서버 host 정 host => "localhost" } } |
filter
logstash에서는 input에서 수집한 데이터를 가공/변형하기 위한 사전정의된 50가지의 filter를 사용할 수 있다. filter에서 사용되는 RegExp 패턴들은 logstash 폴더 내 patterns 폴더 하위에 적재되어 있는데 필요한 경우 이 pattern들을 활용하여 데이터를 좀 더 쉽게 가공할 수 있다(기본적으로 120가지의 패턴을 제공함(https://github.com/logstash/logstash/tree/v1.4.2/patterns)). 다음은 multiline 처리와 grok이라는 비정형 데이터를 파싱하여 정형데이터로 변형해주기 위한 filter를 설정하는 예제이다.
1
2
3
4
5
6
7
8
9
10
11
12 |
filter {} multiline { patterns_dir => "/Users/evilimp/Dev/elk/logstash/patterns" pattern => "(^%{TOMCAT_DATESTAMP})|(^%{CATALINA_DATESTAMP})" negate => true what => "previous" } grok { patterns_dir => "/Users/evilimp/Dev/elk/logstash/patterns" match => [ "message", "%{TOMCATLOG}", "message", "%{CATALINALOG}" ] } } |
일단 filter에서 사용하는 경우에 match 또는 add_field를 이용하여 E/S쪽의 인덱스에 추가적인 컬럼을 생성할 수 있다. grok 패턴처리중 %{NAME:name} 과 같은 형식은 NAME은 grok내 정의된 패턴의 ID값이고, name은 패턴으로 추출된 실제 값이다. 즉, NAME패턴으로 추출된 값이 john이라면 grok 태그 내에서 %{name} 을 사용하면 john이라는 값이 쓰여진다. 물론 match의 경우 내부적인 hash에 name = john 과 같은 key/value 형태로 적재되기 때문에 별도의 작업을 해줄필요는 없다.
1
2
3
4
5
6 |
grok { match => "${NAME:name}" add_field => { "name" => %{name} } } } |
file을 사용할 때와 log4j를 사용할 때는 기본적으로 생성되는 색인구조가 달라지는데, 이는 logstash내부적으로 사용하는 filter가 별도로 정의되어 있기 때문이다. 기본적으로 class, method 등의 정보를 추출하고, message에 실제 log message(%m) 만 적재된다.
grok의 경우 다음URL에서 데이터와 패턴을 체크해볼 수 있음.
grok에서 쓰는 RegEx
주의사항
- logstash의 file tailing은 제일 마지막 발생되는 이벤트는 catch가 안된다.
- 최초 application load 시에 불필요한 로그가 찍히는 경우가 있음.
- 이는 log4j 설정 등으로 해소해야 할 사항으로 판단됨.
'프로젝트 관련 조사 > 로그 관련' 카테고리의 다른 글
[Elasticsearch] Logstash 설치와 기본개념 (0) | 2015.10.15 |
---|---|
중앙집중 로깅 시스템 (0) | 2015.10.15 |
MS 로그 syslog로 전환 (0) | 2015.10.12 |
로그 수집 방법론 (0) | 2015.10.07 |
로그 관련 법규 - 정보통신망법 (0) | 2015.10.07 |