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
[POC] Use ActiveSupport::Logger.broadcast instead of MulticastLogger #17227
Conversation
The code for Ruby's `Logger#datetime_formatter` is as follows: def datetime_format @default_formatter.datetime_format end In the MulticastLogger, neither `@default_formatter` is set or `super` called to set this in the default manner, so this value is always `nil` when this method is called on `MulticastLogger` and thus returns an error. This fixes that by setting `@default_formatter` to `VMDBLogger::Formatter.new` even though it will never be used to log anything, simply because this was what is used by default in the other loggers. Set `@formatter` to `nil` as well as that is also what is done in ruby's source in `Logger#initialize` (to avoid potential warnings).
Very Interesting idea! @bdunne Please review. |
lib/vmdb/loggers.rb
Outdated
@@ -132,11 +132,9 @@ 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_class.new(log_file_path).tap do |logger| | |||
logger.level = Logger::DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need this settings of DEBUG line? If we create the logger and leave it with the default, it should Just Work™
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably don't need this now. I can remove.
spec/lib/vmdb/loggers_spec.rb
Outdated
before do | ||
allow($container_log.logdev).to receive(:write) | ||
end | ||
before(:all) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this before(:all) is not necessary, because we don't run the tests with ENV["CONTAINER"] set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, nvm. I completely misread this because of the shared examples being passed a logger. The structure of the test is confusing in that respect. Perhaps if logger
is just replaced with a differently named variable like test_logger
or something, then it is apparent it's not any built-in logger (which is how I read it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, logger
is coming in from the shared example bit. Changing it to test_logger
or logger_being_tested
(probably the former) is a simple enough change. That said I would probably have to change it in the tests I added in #17223 first.
spec/lib/vmdb/loggers_spec.rb
Outdated
end | ||
|
||
it "responds to #<<" do | ||
expect(subject.respond_to?(:<<)).to be true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expect(subject).to respond_to(:<<)
Maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't know that was an rspec thing. TIL.
Can fix.
spec/lib/vmdb/loggers_spec.rb
Outdated
end | ||
|
||
describe "#datetime_format" do | ||
it "works as expected" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think you need the outer describe here, though this test is kind of useless?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Fryguy This was addressing/testing the issue that @djberg96 had where the method existed, but blew up because @default_formatter
was not set.
Again, though, linking back to my reminder (and mentioned in the description) that this is based off of #17223, so these tests that you are commenting on really should be done in that PR. The point of this branch was to show the changes what was needed to swap this out, and that minimal changes to the tests that were needed to do so. The diff makes it obvious that there was very little in the tests that I needed to change to make this work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think you need the outer
describe
here...
This one is more of a preference in how I like to write specs, but there are two points to it:
- the alternative of
it "#datetime_format works as expected"
reads super dump, and I think it is stupid (sorry, not sugar coating my opinion on this one). - While this is "more to type", it lends it self better to working with multiple checks for a given method and branching contexts.
To my discredit, I did this one poorly. This really should have been two tests (or more), so instead of "works as expected", I would/should have done "doesn't raise and error" and "returns nil". In the document format for rspec
, it then reads as:
#date_format
doesn't raise an error
returns nil
If I had a context
for @default_formatter.datetime_format = "%Y%m%d%H%M"
, then I would read:
#date_format
doesn't raise an error
returns nil
when @default_formatter.datetime_format = "%Y%m%d%H%M"
returns "%Y%m%d%H%M"
Personally, I would rather maintain a style of specs that can be added to without refactoring, and work in a consistent manner, regardless if I am testing with one it
block or many for a particular method. Also sets up a consistent framework when writing tests that a new comer can walk in on and add to easily, compared it "#datetime_format works as expected"
which just promotes chaos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more coming from the viewpoint of "if there's only one test in a describe, and the only test has it 'works'
", then I think it's useless to have the outer describe, when it could just be the "it". But, if the intent was to have more tests, then this is fine.
Adds specs for each of the global loggers around the multicast logger based loggers. Written in a way where we should be able to swap out what we are using under the hood for Multicast logger, and the tests should be a litmus test if we are doing everything correct. Borrowed a decent number of tests from lib/vmdb/loggers/multicast_logger_spec.rb since that has the potential to go away, but we want to test the functionality from that spec file on all of the existing loggers. Hopefully most of the specs here are idempotent, but we will see.
6c5c3f9
to
6910718
Compare
Checked commits NickLaMuro/manageiq@26ed45e~...6910718 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 |
Makes a switch to use `ActiveSupport::Logger.broadcast` which is already used to by the `rails console` to handle printing to both STDOUT and the terminal for the rails log. This just makes use of the same functionality that is there that is pretty much being replicated in the MulticastLogger that we put together ourselves. Minor difference that shouldn't matter: We now only control the level of the main logger, but that really didn't matter since we don't multicast to more than two loggers, and the top one is the one is the only one that matters. The `$container_log` will always be debug anyway, so no need for the level wrap that we had in `MulticastLogger`.
Any reason this is still WIP/POC? Seems like a valid approach |
@Fryguy From @bdunne: #17223 (comment) But, I can un-WIP at this point I guess. |
@NickLaMuro That comment ignores the fact that we still have to support appliances, and thus log files. We can't just delete the code. My terse response was here #17223 (comment) 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we can't delete it yet, let's give this a try 👍
@Fryguy @bdunne Going over some of my old PRs and trying to get them cleaned up, this being one of them From where it looks like we left this one off a month ago, we were basically cool with merging this. That said, in my comment in the related PR, I think merging should happen after merging #17223 since that one is better suited for a backport (if ever necessary). That said, this PR is built off of this one, so it will probably get auto merged anyway with this one. ¯\(°_o)/¯ |
👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice ✂️ ✂️ ✂️
Makes a switch to use
ActiveSupport::Logger.broadcast
which is already used to by therails console
to handle printing to bothSTDOUT
and the log file for the railsdevelopment.log
. This just makes use of the same functionality that is there that is pretty much being replicated in theMulticastLogger
that we put together ourselves.Minor difference that shouldn't matter: We now only control the level of the main logger, and that passes it to other loggers via super. That really didn't matter since we don't multicast to more than two loggers, and the top one is the one is the only one that matters. The
$container_log
will always be debug anyway, so no need for the level wrapper method that we had inMulticastLogger
.Links
MulticastLogger#datetime_formatter
#17223Steps for Testing/QA
Right now, just using tests for QA, but we might want to spin up some containers and see if things are still working as expected.