Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] Use ActiveSupport::Logger.broadcast instead of MulticastLogger #17227

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/vmdb/loggers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,8 @@ def self.create_loggers
private_class_method :create_loggers

def self.create_multicast_logger(log_file_path, logger_class = VMDBLogger)
logger_instance = logger_class.new(log_file_path).tap do |logger|
logger.level = Logger::DEBUG
end
MulticastLogger.new(logger_instance).tap do |l|
l.loggers << $container_log if ENV["CONTAINER"]
logger_class.new(log_file_path).tap do |logger|
logger.extend(ActiveSupport::Logger.broadcast($container_log)) if ENV["CONTAINER"]
end
end
private_class_method :create_multicast_logger
Expand Down
47 changes: 0 additions & 47 deletions lib/vmdb/loggers/multicast_logger.rb

This file was deleted.

43 changes: 0 additions & 43 deletions spec/lib/vmdb/loggers/multicast_logger_spec.rb

This file was deleted.

169 changes: 159 additions & 10 deletions spec/lib/vmdb/loggers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,182 @@ def in_container_env(example)
ENV['CONTAINER'] = old_env
end

shared_examples "has basic logging functionality" do |logger_tested|
subject { logger_tested }
let(:logger1) { subject }
let(:logger2) { $container_log }

before do
allow($container_log.logdev).to receive(:write)
end

before(:all) do
unless ENV['CONTAINER']
logger_tested.extend(ActiveSupport::Logger.broadcast($container_log))
end
end

it "responds to #<<" do
expect(subject).to respond_to(:<<)
end

it "responds to #debug" do
expect(subject).to respond_to(:<<)
end

it "responds to #info" do
expect(subject).to respond_to(:warn)
end

it "responds to #error" do
expect(subject).to respond_to(:error)
end

it "responds to #fatal" do
expect(subject).to respond_to(:fatal)
end

it "responds to #unknown" do
expect(subject).to respond_to(:unknown)
end

describe "#datetime_format" do
it "return nil" do
expect(subject.datetime_format).to be nil
end

it "does not raise an error" do
expect { subject.datetime_format }.to_not raise_error
end
end

# Ripped from lib/vmdb/loggers/multicast_logger_spec.rb, but adapted used
# in a integration spec fashion to test against all of the configured
# loggers, and be idempotent with any of the settings that affect the
# levels and number of loggers (always have the $container_log attached to
# each of the logs tested here).
context "#add" do
context "for info logger levels" do
around do |example|
old_subject_level, subject.level = subject.level, 1
example.run
subject.level = old_subject_level
end

it "forwards to the other loggers" do
expect(logger1).to receive(:add).with(1, nil, "test message").and_call_original
expect(logger2).to receive(:add).with(1, nil, "test message").and_call_original

subject.info("test message")
end
end

context "for higher logger levels" do
around do |example|
old_logger_1_level, logger1.level = logger1.level, 0
old_subject_level, subject.level = subject.level, 1
example.run
subject.level = old_subject_level
logger1.level = old_logger_1_level
end

it "only forwards the message if the severity is correct" do
expect(logger1.logdev).not_to receive(:write).with("test message")
expect(logger2.logdev).not_to receive(:write).with("test message")

subject.debug("test message")
end
end
end

context "#level=" do
around do |example|
old_subject_level, subject.level = subject.level, 0
example.run
subject.level = old_subject_level
end

it "updates the log level on all backing devices" do
expect(logger1.level).to eq(0)
expect(logger2.level).to eq(0)
expect(subject.level).to eq(0)
subject.level = 3
expect(logger1.level).to eq(3)
expect(logger2.level).to eq(0) # $container_log is always DEBUG
expect(subject.level).to eq(3)
end
end

context "#<<" do
it "forwards to the other loggers" do
expect(logger1).to receive(:<<).with("test message").and_call_original
expect(logger2).to receive(:<<).with("test message")

subject << "test message"
end
end
end

context "for all multicast loggers" do
[
$log, $rails_log, $api_log, $miq_ae_logger, $aws_log, $azure_log,
$cn_monitoring_log, $datawarehouse_log, $fog_log, $kube_log, $lenovo_log,
$nuage_log, $policy_log, $rhevm_log, $scvmm_log, $vcloud_log, $vim_log,
$websocket_log
].each do |logger|
context "for the #{File.basename(logger.filename)}" do
include_examples "has basic logging functionality", logger.dup
end
end
end

describe "#create_multicast_logger (private)" do
it "defaults the lower level loggers to `DEBUG`" do
it "defaults the loggers to the default level (INFO)" do
log = described_class.send(:create_multicast_logger, log_file)

expect(log.loggers.first.level).to eq(Logger::DEBUG)
expect(log.loggers.to_a.size).to eq(1)
expect(log.level).to eq(Logger::INFO)
end

it "does not broadcast to $container_log by default" do
io = StringIO.new
log = described_class.send(:create_multicast_logger, io)

expect(log).to receive(:add).with(0, nil, "foo").once.and_call_original
expect($container_log).to receive(:add).with(0, nil, "foo").never
log.debug "foo"
end

context "in a container environment" do
around { |example| in_container_env(example) }

it "sets logger_instance and $container_log to debug" do
it "sets logger_instance to INFO and $container_log to DEBUG" do
log = described_class.send(:create_multicast_logger, log_file)

expect(log.loggers.first.level).to eq(Logger::DEBUG)
expect(log.loggers.to_a.last.level).to eq(Logger::DEBUG)
expect(log.level).to eq(Logger::INFO)
expect($container_log.level).to eq(Logger::DEBUG)
end

it "broadcasts to $container_log and the base logger" do
io = StringIO.new
log = described_class.send(:create_multicast_logger, io)

expect(log).to receive(:add).with(0, nil, "foo").once.and_call_original
expect($container_log).to receive(:add).with(0, nil, "foo").once
log.debug "foo"
end
end
end

describe "#apply_config_value (private)" do
before do
allow($log).to receive(:info)
end

it "will update the main lower level logger instance" do
log = described_class.send(:create_multicast_logger, log_file)
described_class.send(:apply_config_value, {:foo => :info}, log, :foo)

expect(log.loggers.first.level).to eq(Logger::INFO)
expect(log.loggers.to_a.size).to eq(1)
expect(log.level).to eq(Logger::INFO)
end

context "in a container environment" do
Expand All @@ -46,8 +195,8 @@ def in_container_env(example)
log = described_class.send(:create_multicast_logger, log_file)
described_class.send(:apply_config_value, {:foo => :info}, log, :foo)

expect(log.loggers.first.level).to eq(Logger::INFO)
expect(log.loggers.to_a.last.level).to eq(Logger::DEBUG)
expect(log.level).to eq(Logger::INFO)
expect($container_log.level).to eq(Logger::DEBUG)
end
end
end
Expand Down