mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 22:57:16 -04:00
Currently, LS does not respect fatal errors such as java.lang.OutOfMemoryError and continues executing. This is dangerous since JVM errors are a legitimate reason to halt the process and not continue processing. Additionally: - make sure we log the full stack-trace on fatal errors - halt the JVM wout executing finalizers/hook (scissors on how ES handles uncaught exceptions) - also, we should now be aware of a potentially unexpectedly dying thread Back-port of #12470
74 lines
2.8 KiB
Ruby
74 lines
2.8 KiB
Ruby
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
# license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright
|
|
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
# the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
require_relative '../framework/fixture'
|
|
require_relative '../framework/helpers'
|
|
require_relative '../framework/settings'
|
|
require_relative '../services/logstash_service'
|
|
require "logstash/devutils/rspec/spec_helper"
|
|
|
|
describe "uncaught exception" do
|
|
|
|
before(:all) do
|
|
@fixture = Fixture.new(__FILE__)
|
|
@logstash = @fixture.get_service("logstash")
|
|
end
|
|
|
|
after(:each) { @logstash.teardown }
|
|
|
|
let(:timeout) { 90 } # seconds
|
|
let(:temp_dir) { Stud::Temporary.directory("logstash-error-test") }
|
|
|
|
it "halts LS on fatal error" do
|
|
config = "input { generator { count => 1 message => 'a fatal error' } } "
|
|
# inline Ruby filter seems to catch everything (including java.lang.Error) so we exercise a thread throwing
|
|
config += "filter { ruby { code => 'Thread.start { raise java.lang.AssertionError.new event.get(\"message\") }' } }"
|
|
|
|
spawn_logstash_and_wait_for_exit! config, timeout
|
|
|
|
expect(@logstash.exit_code).to be 120
|
|
|
|
log_file = "#{temp_dir}/logstash-plain.log"
|
|
expect( File.exists?(log_file) ).to be true
|
|
expect( File.read(log_file) ).to match /\[FATAL\]\[org.logstash.Logstash.*?java.lang.AssertionError: a fatal error/m
|
|
end
|
|
|
|
it "logs unexpected exception (from Java thread)" do
|
|
config = "input { generator { count => 1 message => 'unexpected' } } "
|
|
config += "filter { ruby { code => 'java.lang.Thread.new { raise java.io.EOFException.new event.get(\"message\") }.start; sleep(1.5)' } }"
|
|
|
|
spawn_logstash_and_wait_for_exit! config, timeout
|
|
|
|
expect(@logstash.exit_code).to be 0 # normal exit
|
|
|
|
log_file = "#{temp_dir}/logstash-plain.log"
|
|
expect( File.exists?(log_file) ).to be true
|
|
expect( File.read(log_file) ).to match /\[ERROR\]\[org.logstash.Logstash.*?uncaught exception \(in thread .*?java.io.EOFException: unexpected/m
|
|
end
|
|
|
|
def spawn_logstash_and_wait_for_exit!(config, timeout)
|
|
@logstash.spawn_logstash('-w', '1', '--path.logs', temp_dir, '-e', config)
|
|
|
|
time = Time.now
|
|
while (Time.now - time) < timeout
|
|
sleep(0.1)
|
|
break if @logstash.exited?
|
|
end
|
|
raise 'LS process did not exit!' unless @logstash.exited?
|
|
end
|
|
|
|
end
|