ELK 조합으로 로그 수집을 할 때 생성되는 로그에 대한 관리 기법에 대한 내용이며,

실제 로그 파일을 최초 읽어 들일 때 어떤 기준으로 읽고, 관리를 할지에 대한 내용을 확인할 수 있습니다.

 

 

Logstash는Logcollector로서다양한Input/Output Plugin을지원하기때문에손쉽게로그취합시편하게작업할수있다.

예를들어, Logstash 2.3에서는20개이상의 Output Plugin이지원되고있는데,

Log를Elasticsearch에싶으면Elasticsearch Plugin을사용하면되고, Configuration만바꾸면손쉽게Kafka에도저장할수있다.

즉, 직접Kafka Producer를개발하지않아도되는것이큰장점중의하나이다.

편리함때문에Logstash를도입하거나도입을테스트하는곳이늘어나고있는데,

Logstash의Offset 기법을제대로파악하지못하는경우, 일부로그가유실될수있다.

 

따라서본글에서는Logstash의Offset 관리기법에대해서적어볼까한다.

 

start_position

Logstash를처음사용할때제일헷갈리는것이 start_position이다. 이름에서알수있다시피, Lostash를시작할때file의어디서부터읽을지를결정하는설정이며, 다음과같은2가지를지원한다.

·         beginning

·         end (default)

주의할점은이설정은file을 최초 읽을때만적용된다는점이다. 실수하기쉬운것이, start_position => "beginning"인경우Logstash를여러번restart하더라도항상동일한내용이출력될것이라생각하는게그렇지않다.

 

since_db

Logstash가최초시작될때는file을읽을위치가 start_position에의해결정되지만, 이후실행시에는sincedb에저장된offset부터읽기시작한다. 아래의예를보자.

$ cat ~/.sincedb_a8ae6517118b64cf101eba5a72c366d4

22253332 1 3 14323

각각의항목은다음과같은것을의미한다.

1.     첫번째필드: file의inode

2.     두번째필드: file system의major device number

3.     세번째필드: file system의minor device number

4.     네번째필드: current offset

즉, 위의예에서22253332번파일은현재14323번offset까지처리가되었다는것을의미한다. 이상태에서Logstash를재실행하는경우 start_position 값과상관없이14323 offset부터file을읽기시작한다.

Logstash를테스트하는동안에는이sincdedb 때문에테스트가좀번거롭다. 이경우(sincedb_path)[https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html#plugins-inputs-file-sincedb_path)를/dev/null로설정하면된다.

input {

    file {

        path => "/path/to/file"

        start_position => "beginning"

        sincedb_path => "/dev/null"

    }  

}

Log Rotate 사용시, Log 유실이없으려면?

Logstash는Input file이Rotate되더라도로그를잘수집한다. 단, 유실이없으려면Logstash의특성을잘이해해야한다. (Log rotate에는move 방식과copy & truncate 방식2가지가있는데Logstash는두가지모두잘작동한다)

Logstash Manaual을읽어보면File rotation에대해서다음과같이설명되어있다.

File rotation is detected and handled by this input, regardless of whether the file is rotated via a rename or a copy operation. To support programs that write to the rotated file for some time after the rotation has taken place, include both the original filename and the rotated filename (e.g. /var/log/syslog and /var/log/syslog.1) in the filename patterns to watch (the path option). Note that the rotated filename will be treated as a new file so if start_position is set to beginning the rotated file will be reprocessed. With the default value of start_position (end) any messages written to the end of the file between the last read operation prior to the rotation and its reopening under the new name (an interval determined by the stat_interval and discover_interval options) will not get picked up.

위말을쉽게이해하는사람이면본문서를더이상읽을필요가없다.

우선Logstash 설정2개에대해서알고있어야한다. 성능향상을위하여Logstash는다음과같은설정2개를사용한다.

·         stat_interval

o    파일이갱신되었는지확인하는주기이다. 기본값은1초이다.

·         discover_interval

o    file pattern에맞는file이생성되었는지확인하는주기이다.

위두가지변수와 start_position의의미만알고있다면영문메뉴얼의설명을쉽게이해할수있다.

Log rotate 시나리오에서Logstash 작동방식

Log rotate를위해다음과같이file path에pattern을주었다고가정한다.

path => "/var/log/syslog*"

시간

이벤트

행동

t초

stat_interval 경과

/var/log/syslog에서sincedb에기록된offset 이후의내용을읽는다.

t+1초

N/A

/var/log/syslog에신규로그가쌓인다

t+2초

Log Rotate

/var/log/syslog가 /var/log/syslog.1로rename됨(inode가변하지않았으므로Logstash 입장에서는신규파일이아니다.

t+3초

Log Rotate

/var/log/syslog 재생성(신규파일이생성된것이다.)

t+4초

N/A

/var/log/syslog에신규로그가쌓이기시작한다.

t+5초

stat_interval 경과

/var/log/syslog.1의since에기록된offset 이부터읽기시작함. 즉, t+1초부터쌓인로그는유실없이처리됨

t+6초

discover_interval경과

/var/log/syslog가새로생긴것을인지한뒤 start_position부터읽기시작함

start_position => "end"인경우유실가능성존재

Logstash가새로생긴 /var/log/syslog를최초읽는시점은t+6이다. 이때 start_position => "end"이므로(t+4)초부터(t+6)초사이에쌓인로그는유실된다.

따라서 start_position => "beginning"으로설정해야만유실없이사용할수있다.

기타중요한설정

sincedb_write_interval

비교적쉽게이해할수있는설정인데, Logstash가처리중인offset을얼마의주기로sincedb에기록할지지정하는설정이며기본값은15초이다. start_position, stat_interval, discover_interval은‘유실없는처리’ 때문에중요하다면sincedb_write_interval은중복유입에관련된설정이기때문에중요하다.

예를들어t초sincedb에offset 1000을기록후, (t+14)초에offset 2000까지읽은뒤, Logstash가죽었다고하자. sincedb에는1000이적혀있으므로Logstash를restart하는경우1001~2000까지는중복처리된다.

match되는파일이복수개일때, 처리방식

file이1개일때log는sequential하게시간순으로처리되지만, file이여러개인경우처리되는순서는시간순인것을보장하지않는다.

예를들어다음과같은파일A, B가있다고가정하자.

+-------------+  +-------------+

|file A의내용|  |file B의내용|

+-------------+  +-------------+

| t1-A        |  | t1-B        |

| t2-A        |  | t2-B        |

| t3-A        |  | t3-B        |

| t4-A        |  | t4-B        |

| t5-A        |  | t5-B        |

+-------------+  +-------------+

t1, t2, …, t5을의미한다(즉, t1이t5보다빠르다). 이때Logstash를실행시켜서stdout으로출력하면어떤순으로출력될까?

1.     t1-A => t1-B => t2-A => t2-B … => t5-A => t5-B

2.     t1-A => t2-A => t3-A … => t3-B => t4-B => t5-B

정답은2번이다. 즉, Logstash output이Cassandra인경우Cassandra 입장에서는로그가시간순으로입력되지않는다. Time series log를column에저장하는경우순서가뒤죽박죽될수있다.

 

 

출처: http://jason-heo.github.io/elasticsearch/2016/02/28/logstash-offset.html