728x90
반응형

로그를 쌓는데 Logstash에서 간헐적으로 OOM 에러가 발생했었다.

[ERROR][logstash.pipeline ] Exception in pipelineworker, the pipeline stopped processing new events, please check your filter configuration and restart Logstash. {:pipeline_id=>"mds", "exception"=>"Java heap space", "backtrace"=>["org.jruby.util.ByteList.<init>(ByteList.java:92)", "org.jruby.util.ByteList.dup(ByteList.java:328)", "org.jruby.util.ByteList.dup(ByteList.java:300)", "org.jruby.RubyString.doClone(RubyString.java:1346)", "org.logstash.Cloner.deep(Cloner.java:25)", "org.logstash.Cloner.deepMap(Cloner.java:65)", "org.logstash.Cloner.deep(Cloner.java:21)", "org.logstash.Event.clone(Event.java:310)", "org.logstash.ext.JrubyEventExtLibrary$RubyEvent.rubyClone(JrubyEventExtLibrary.java:147)", "org.logstash.ext.JrubyEventExtLibrary$RubyEvent.rubyClone(JrubyEventExtLibrary.java:142)", "java.base/java.lang.invoke.DirectMethodHandle$Holder.invokeSpecial(DirectMethodHandle$Holder)", "java.base/java.lang.invoke.LambdaForm$MH/0x00000008406a3440.invoke(LambdaForm$MH)", "java.base/java.lang.invoke.DelegatingMethodHandle$Holder.delegate(DelegatingMethodHandle$Holder)", "java.base/java.lang.invoke.LambdaForm$MH/0x000000084069e840.guard(LambdaForm$MH)", "java.base/java.lang.invoke.DelegatingMethodHandle$Holder.delegate(DelegatingMethodHandle$Holder)", "java.base/java.lang.invoke.LambdaForm$MH/0x000000084069e840.guard(LambdaForm$MH)", "java.base/java.lang.invoke.Invokers$Holder.linkToCallSite(Invokers$Holder)", "usr.share.logstash.vendor.bundle.jruby.$2_dot_5_dot_0.gems.logstash_minus_filter_minus_split_minus_3_dot_1_dot_7.lib.logstash.filters.split.RUBY$block$filter$1(/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-filter-split-3.1.7/lib/logstash/filters/split.rb:88)", "java.base/java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(DirectMethodHandle$Holder)", "java.base/java.lang.invoke.LambdaForm$MH/0x0000000841005040.invoke(LambdaForm$MH)", "java.base/java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder)", "org.jruby.runtime.CompiledIRBlockBody.yieldDirect(CompiledIRBlockBody.java:146)", "org.jruby.runtime.BlockBody.yield(BlockBody.java:114)", "org.jruby.runtime.Block.yield(Block.java:165)", "org.jruby.RubyArray.each(RubyArray.java:1792)", "java.base/java.lang.invoke.LambdaForm$DMH/0x000000084069ac40.invokeVirtual(LambdaForm$DMH)", "java.base/java.lang.invoke.LambdaForm$MH/0x00000008406b3440.invoke(LambdaForm$MH)", "java.base/java.lang.invoke.LambdaForm$MH/0x00000008406c2840.guardWithCatch(LambdaForm$MH)", "java.base/java.lang.invoke.LambdaForm$MH/0x00000008406c3440.invoke(LambdaForm$MH)", "java.base/java.lang.invoke.DelegatingMethodHandle$Holder.delegate(DelegatingMethodHandle$Holder)", "java.base/java.lang.invoke.LambdaForm$MH/0x0000000840674040.guard(LambdaForm$MH)", "java.base/java.lang.invoke.DelegatingMethodHandle$Holder.delegate(DelegatingMethodHandle$Holder)"], :thread=>"#<Thread:0x33a1a707 sleep>"}
[ERROR][org.logstash.Logstash ] java.lang.OutOfMemoryError: Java heap space
[WARN ][logstash.pipeline ] CAUTION: Recommended inflight events max exceeded! Logstash will run with up to 16000 events in memory in your current configuration. If your message sizes are large this may cause instability with the default heap size. Please consider setting a non-standard heap size, changing the batch size (currently 2000), or changing the number of pipeline workers (currently 8) {:pipeline_id=>"mds", :thread=>"#<Thread:0x705f801 run>"}

처음에는 JVM 옵션을 기본 설정인 -Xms1g -Xmx1g 로 하고 있어 이를 늘려서 재시작을 했다.

 

하지만 곧 다시 에러가 발생하면서 로그를 더이상 받지 못했다.

 

그래서 Kafka Input 설정 중에 max_poll_records 를 변경하면서 모니터링했다.

 

몇 시간 동안 잘 되는가 싶더니 곧 에러가 나더니 다시 로그 수집을 못하고 있었다.

 

filter에서 사용하는 부분을 검사하다 이번에 추가된 split이 문제가 있는 것 같아 구글링을 했다.

 

구글링을 해보니 해당 플러그인에 메모리 누수 문제가 발생하는 것 같았다.

 

그래서 이를 대체할 방법을 찾다가 다음과 같이 해보라는 글을 보고 따라해봤다.

def register(params)
    @field = params['field']
    @target = params['target']
end

def filter(event)
    data = event.get(@field)
    event.remove(@field)
    a = []
    data.each { |x|
        e = event.clone
        e.set(@target, x)
        a << e
    }
    a
end
json {
    source => "message"
    remove_field => [ "message" ]
}
ruby {
    path => '/my/path/splitData.rb'
    script_params => { field => "data" target => "data" }
}

split을 변경한 이후로 메모리 누수로 인하여 로그 수집이 중단되는 현상이 나오진 않았다.

 

참고 문헌

  1. https://github.com/logstash-plugins/logstash-filter-split/issues/35

  2. https://discuss.elastic.co/t/how-to-split-into-multiple-events-dynamically-for-a-given-json-tried-from-various-question-in-forums/167745/11

반응형

+ Recent posts