2025년 1월 18일 토요일

Logstash 필터 ruby - 5th

ruby 필터는 == 등의 비교 연산자를 지원하지 않는다. 다음은 include 메소드를 이용한 ? 검사.
ruby {
 code => "
  if event.get('message').include?('?')
   event.set('result', 'TRUE')
  else
   event.set('result', 'FALSE')
  end
 "
}
[2025-01-18T14:56:19,606][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
{
    "message" => "192.168.71.168 - - [12/Oct/2015:02:42:00 +0900] \"GET /bbs/view.php?board_id=kor%5Fmedia&gul_no=1106&idx=17&m=4&upage=25&tpage=&PAGE=4 HTTP/1.1\" 200 37727\r",
     "result" => "TRUE"
}
{
    "message" => "192.168.71.168 - - [12/Oct/2015:02:42:00 +0900] \"GET /bbs/view.html HTTP/1.1\" 200 37727\r",
     "result" => "FALSE"
}

정규표현식 검사는 match 메소드로 가능.
ruby {
 code => "
  if event.get('message').match('\?')
   event.set('result', 'TRUE')
  else
   event.set('result', 'FALSE')
  end
 "
}

그런데 code 표현식 구분기호를 '로 바꾸면서 충돌 방지를 위해 표현식내에 사용된 '"로 바꾸니 에러 발생. 순수문자 ?(\?)를 수량자로 인식한다.
ruby {
 code => '
  if event.get("message").match("\?")
   event.set("result", "TRUE")
  else
   event.set("result", "FALSE")
  end
 '
}
[2025-01-18T15:02:16,612][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2025-01-18T15:02:16,740][ERROR][logstash.filters.ruby    ][main][62b3883710cf5e6539519c02d2e859b71543aa213032326fbf070fa80051a3f3] Ruby exception occurred: target of repeat operator is not specified: /?/ {:class=>"RegexpError", :backtrace=>["org/jruby/RubyString.java:1754:in `match'", "(ruby filter code):3:in `block in register'", "D:/ELK/logstash-8.17.0/vendor/bundle/jruby/3.1.0/gems/logstash-filter-ruby-3.1.8/lib/logstash/filters/ruby.rb:96:in `inline_script'", "D:/ELK/logstash-8.17.0/vendor/bundle/jruby/3.1.0/gems/logstash-filter-ruby-3.1.8/lib/logstash/filters/ruby.rb:89:in `filter'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/filters/base.rb:158:in `do_filter'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/filters/base.rb:176:in `block in multi_filter'", "org/jruby/RubyArray.java:1981:in `each'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/filters/base.rb:173:in `multi_filter'", "org/logstash/config/ir/compiler/AbstractFilterDelegatorExt.java:133:in `multi_filter'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/java_pipeline.rb:308:in `block in start_workers'"]}
[2025-01-18T15:02:16,742][ERROR][logstash.filters.ruby    ][main][62b3883710cf5e6539519c02d2e859b71543aa213032326fbf070fa80051a3f3] Ruby exception occurred: target of repeat operator is not specified: /?/ {:class=>"RegexpError", :backtrace=>["org/jruby/RubyString.java:1754:in `match'", "(ruby filter code):3:in `block in register'", "D:/ELK/logstash-8.17.0/vendor/bundle/jruby/3.1.0/gems/logstash-filter-ruby-3.1.8/lib/logstash/filters/ruby.rb:96:in `inline_script'", "D:/ELK/logstash-8.17.0/vendor/bundle/jruby/3.1.0/gems/logstash-filter-ruby-3.1.8/lib/logstash/filters/ruby.rb:89:in `filter'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/filters/base.rb:158:in `do_filter'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/filters/base.rb:176:in `block in multi_filter'", "org/jruby/RubyArray.java:1981:in `each'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/filters/base.rb:173:in `multi_filter'", "org/logstash/config/ir/compiler/AbstractFilterDelegatorExt.java:133:in `multi_filter'", "D:/ELK/logstash-8.17.0/logstash-core/lib/logstash/java_pipeline.rb:308:in `block in start_workers'"]}
{
    "message" => "192.168.71.168 - - [12/Oct/2015:02:42:00 +0900] \"GET /bbs/view.php?board_id=kor%5Fmedia&gul_no=1106&idx=17&m=4&upage=25&tpage=&PAGE=4 HTTP/1.1\" 200 37727\r",
       "tags" => [
        [0] "_rubyexception"
    ]
}
{
    "message" => "192.168.71.168 - - [12/Oct/2015:02:42:00 +0900] \"GET /bbs/view.html HTTP/1.1\" 200 37727\r",
       "tags" => [
        [0] "_rubyexception"
    ]
}

\를 하나 더 추가해줘야 예외처리가 됨. 인용부호 종류에 따라 동작 방식이 바뀌다니 신기하네(..)
ruby {
 code => '
  if event.get("message").match("\\?")
   event.set("result", "TRUE")
  else
   event.set("result", "FALSE")
  end
 '
}
[2025-01-18T15:02:55,821][INFO ][logstash.agent           ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}
[2025-01-18T15:02:55,823][INFO ][filewatch.observingtail  ][main][925210a49f665e5510840791e908400bcb21ff21428156584c5f572f276da2fe] START, creating Discoverer, Watch with file and sincedb collections
{
    "message" => "192.168.71.168 - - [12/Oct/2015:02:42:00 +0900] \"GET /bbs/view.html HTTP/1.1\" 200 37727\r",
     "result" => "FALSE"
}
{
    "message" => "192.168.71.168 - - [12/Oct/2015:02:42:00 +0900] \"GET /bbs/view.php?board_id=kor%5Fmedia&gul_no=1106&idx=17&m=4&upage=25&tpage=&PAGE=4 HTTP/1.1\" 200 37727\r",
     "result" => "TRUE"
}

정규표현식 구분기호는 /만 써야겠다.
ruby {
 code => '
  if event.get("message").match(/\?/)
   event.set("result", "TRUE")
  else
   event.set("result", "FALSE")
  end
 '
}

댓글 없음:

댓글 쓰기

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