mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 06:37:19 -04:00
Bug Fix: Fix ability to change log level via the API
The ability to change the log level as described at https://www.elastic.co/guide/en/logstash/current/logging.html#_logging_apis appears to no longer work. The root cause of this issue is that log4j2 context we initialize is different from the log4j2 context that we are setting via the API. The fix here is to mirror the functionality of org.apache.logging.log4j.core.config.Configurator.setLevel Java method, but instead use the logging_context initialized in our code via JRuby. Fixes #7277 Fixes #7321
This commit is contained in:
parent
254d58d3a4
commit
55979c3a07
3 changed files with 94 additions and 1 deletions
|
@ -7,6 +7,7 @@ module LogStash
|
|||
java_import org.apache.logging.log4j.LogManager
|
||||
java_import org.apache.logging.log4j.core.config.Configurator
|
||||
java_import org.apache.logging.log4j.core.config.DefaultConfiguration
|
||||
java_import org.apache.logging.log4j.core.config.LoggerConfig
|
||||
|
||||
class Logger
|
||||
@@config_mutex = Mutex.new
|
||||
|
@ -65,7 +66,7 @@ module LogStash
|
|||
end
|
||||
|
||||
def self.configure_logging(level, path = LogManager::ROOT_LOGGER_NAME)
|
||||
@@config_mutex.synchronize { Configurator.setLevel(path, Level.valueOf(level)) }
|
||||
@@config_mutex.synchronize { set_level(level, path) }
|
||||
rescue Exception => e
|
||||
raise ArgumentError, "invalid level[#{level}] for logger[#{path}]"
|
||||
end
|
||||
|
@ -90,6 +91,30 @@ module LogStash
|
|||
def self.get_logging_context
|
||||
return @@logging_context
|
||||
end
|
||||
|
||||
# Clone of org.apache.logging.log4j.core.config.Configurator.setLevel(), but using initialized @@logging_context
|
||||
def self.set_level(_level, path)
|
||||
configuration = @@logging_context.getConfiguration()
|
||||
level = Level.valueOf(_level)
|
||||
if path.nil? || path.strip.empty?
|
||||
root_logger = configuration.getRootLogger()
|
||||
if root_logger.getLevel() != level
|
||||
root_logger.setLevel(level)
|
||||
@@logging_context.updateLoggers()
|
||||
end
|
||||
else
|
||||
package_logger = configuration.getLoggerConfig(path)
|
||||
if package_logger.name != path #no package logger found
|
||||
configuration.addLogger(path, LoggerConfig.new(path, level, true))
|
||||
@@logging_context.updateLoggers()
|
||||
elsif package_logger.getLevel() != level
|
||||
package_logger.setLevel(level)
|
||||
@@logging_context.updateLoggers()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private_class_method :set_level
|
||||
end
|
||||
|
||||
class SlowLogger
|
||||
|
|
|
@ -33,4 +33,13 @@ class MonitoringAPI
|
|||
JSON.parse(resp)
|
||||
end
|
||||
|
||||
def logging_get
|
||||
resp = Manticore.get("http://localhost:9600/_node/logging").body
|
||||
JSON.parse(resp)
|
||||
end
|
||||
|
||||
def logging_put(json_body)
|
||||
resp = Manticore.put("http://localhost:9600/_node/logging", {headers: {"Content-Type" => "application/json"}, body: json_body }).body
|
||||
JSON.parse(resp)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -77,4 +77,63 @@ describe "Test Monitoring API" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "can configure logging" do
|
||||
logstash_service = @fixture.get_service("logstash")
|
||||
logstash_service.start_with_stdin
|
||||
logstash_service.wait_for_logstash
|
||||
|
||||
Stud.try(max_retry.times, [StandardError, RSpec::Expectations::ExpectationNotMetError]) do
|
||||
# monitoring api can fail if the subsystem isn't ready
|
||||
result = logstash_service.monitoring_api.logging_get rescue nil
|
||||
expect(result).not_to be_nil
|
||||
expect(result["loggers"].size).to be > 0
|
||||
#default
|
||||
logging_get_assert logstash_service, "INFO", "TRACE"
|
||||
|
||||
#root logger - does not apply to logger.slowlog
|
||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger." => "WARN"}.to_json)
|
||||
logging_get_assert logstash_service, "WARN", "TRACE"
|
||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger." => "INFO"}.to_json)
|
||||
logging_get_assert logstash_service, "INFO", "TRACE"
|
||||
|
||||
#package logger
|
||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger.logstash.agent" => "DEBUG"}.to_json)
|
||||
expect(logstash_service.monitoring_api.logging_get["loggers"]["logstash.agent"]).to eq ("DEBUG")
|
||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger.logstash.agent" => "INFO"}.to_json)
|
||||
logging_get_assert logstash_service, "INFO", "TRACE"
|
||||
|
||||
#parent package loggers
|
||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger.logstash" => "ERROR"}.to_json)
|
||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger.slowlog" => "ERROR"}.to_json)
|
||||
|
||||
result = logstash_service.monitoring_api.logging_get
|
||||
result["loggers"].each do | k, v |
|
||||
#since we explicitly set the logstash.agent logger above, the parent logger will not take precedence
|
||||
if k.eql? "logstash.agent"
|
||||
expect(v).to eq("INFO")
|
||||
else
|
||||
expect(v).to eq("ERROR")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def logging_get_assert(logstash_service, logstash_level, slowlog_level)
|
||||
result = logstash_service.monitoring_api.logging_get
|
||||
result["loggers"].each do | k, v |
|
||||
if k.start_with? "logstash"
|
||||
expect(v).to eq(logstash_level)
|
||||
elsif k.start_with? "slowlog"
|
||||
expect(v).to eq(slowlog_level)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def logging_put_assert(result)
|
||||
expect(result["acknowledged"]).to be(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue