2020년 2월 24일 월요일

Logstash 필터 ruby - 4th

ruby 필터는 데이터 필터링 과정에서 ruby 언어의 다양한 기능을 사용할 수 있게 해준다. 엘라스틱의 사용 편의성을 크게 높일 수 있다는 얘기. 다음은 간단한 테스트를 위한 설정.
input {
 stdin {}
}

output {
 stdout {}
}

input 플러그인 stdin은 로그스태시 실행창에서 데이터를 직접 입력하는 기능을 제공한다. 참고로 stdin을 사용할 땐 로그스태시 재시작 설정(config.reload.automatic: true)이 동작하지 않음.
[2020-02-24T20:48:20,044][ERROR][logstash.agent           ] Failed to execute action {:id=>:main, :action_type=>LogStash::ConvergeResult::FailedAction, :message=>"Cannot reload pipeline, because the existing pipeline is not reloadable", :backtrace=>nil}

로그스태시가 실행된 후, 시간 정보(10:10:48, 2000-01-30)를 입력해보자.
[2020-02-24T20:54:05,169][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9601}
10:10:48
{
       "message" => "10:10:48\r",
    "@timestamp" => 2020-02-24T11:54:10.559Z,
      "@version" => "1",
          "host" => "MHKANG"
}
2000-01-30
{
       "message" => "2000-01-30\r",
    "@timestamp" => 2020-02-24T11:54:13.825Z,
      "@version" => "1",
          "host" => "MHKANG"
}

입력한 데이터가 message 필드를 통해서 전달된다. 다음은 입력한 시간 정보를 @timestamp에 매핑하기 위한 date 필터 설정. message 필드에 포함된 줄바꿈 문자(\r)를 제거하기 위해 mutate strip 옵션을 사용했다.
filter {
 if ":" in [message] {
  mutate { strip => "message" }
  date { match => [ "message", "HH:mm:ss" ] }
 } else {
  mutate { strip => "message" }
  date { match => [ "message", "yyyy-MM-dd" ] }
 }
}

다음은 실행 결과.
[2020-02-24T21:15:02,492][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9601}
10:10:48
{
      "@version" => "1",
       "message" => "10:10:48",
          "host" => "MHKANG",
    "@timestamp" => 2020-01-01T01:10:48.000Z
}
2000-01-30
{
      "@version" => "1",
       "message" => "2000-01-30",
          "host" => "MHKANG",
    "@timestamp" => 2000-01-29T15:00:00.000Z
}

꽤 복잡한 필터링 과정을 거쳐서 원하는 시간 필드를 만들었다. 이때 ruby의 time 함수 기능을 이용하면 좀 더 우아한(?) 필터링이 가능하다.
filter {
 ruby { 
  code => "event.set('timestamp', Time.parse(event.get('message')))" 
 }
}

실행 결과는 다음과 같다. message 필드의 문자열 데이터가 timestamp의 시간 데이터로 바뀜.
[2020-02-24T21:24:23,223][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9601}
10:10:48
{
          "host" => "MHKANG",
     "timestamp" => 2020-02-24T01:10:48.000Z,
    "@timestamp" => 2020-02-24T12:24:27.732Z,
       "message" => "10:10:48\r",
      "@version" => "1"
}
2000-01-30
{
          "host" => "MHKANG",
     "timestamp" => 2000-01-29T15:00:00.000Z,
    "@timestamp" => 2020-02-24T12:24:32.353Z,
       "message" => "2000-01-30\r",
      "@version" => "1"
}

다음은 엘라스틱에 저장한 결과. @timestamp와 별도로 date 유형 필드가 추가된다.


데이터는 시간 포맷이지만 유형이 date가 아닌 필드 처리할 때 유용할 듯. 참고로 같은 date 유형 필드를 만들어주지만 ruby와 date 필터의 동작 방식은 약간 다르다.

[ 시간 정보가 없을 때 ]
  • date와 ruby 모두 00:00:00으로 셋팅

[ 날짜 정보가 없을 때 ]
  • date : 실행 연도의 첫 날짜로 셋팅(2020-01-01)
  • ruby : 실행 시점의 날짜로 셋팅(2020-02-24)

관련 글

댓글 없음:

댓글 쓰기

크리에이티브 커먼즈 라이선스