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
Refactor by introducing a formatter that sends logging events to multiple formatters #24
Comments
@robd What do you think of this proposal? Step 1: Introduce
Step 2: Change This would be a simple refactor to allow for step 3. module SSHKit
module Formatter
class Airbrussh < Airbrussh::DelegatingFormatter
def initialize(io, config=Airbrussh.configuration)
super
formatters << Airbrussh::Formatter.new(io, config)
end
end
end
end Step 3: Move log file code out of
Step 4: Wire it all up Now we have two formatters that are cleanly separated, and the top level module SSHKit
module Formatter
class Airbrussh < Airbrussh::DelegatingFormatter
def initialize(io, config=Airbrussh.configuration)
super
file = config.log_file
formatters << Airbrussh::Formatter.new(io, config)
formatters << Airbrussh::PrettyLogFileFormatter.new(file) unless file.nil?
end
end
end
end How does that look? |
I think that looks great. Here are a couple of thoughts:
namespace :deploy do
task :failed do
if (log_file = Airbrussh.configuration.log_file)
err = Airbrussh::Console.new($stderr)
err.print_line
err.print_line(red("** DEPLOY FAILED"))
err.print_line(yellow("** Refer to #{log_file} for details. "\
"Here are the last 20 lines:"))
err.print_line
system("tail -n 20 #{log_file.shellescape} 1>&2")
end
end
end
module SSHKit
module Formatter
class Airbrussh < Airbrussh::DelegatingFormatter
def initialize(io, config=Airbrussh.configuration)
super(config.formatters(io))
end
end
end
end
# Configuration
def formatters(io)
formatters = [Airbrussh::Formatter.new(io, self)]
formatters << Airbrussh::PrettyLogFileFormatter.new(@log_file, formatters.first) unless @log_file.nil?
formatters
end
# PrettyLogFileFormatter
def write_banner
return unless config.banner
if config.banner == :auto
return if @log_file.nil?
normal_formatter.info("Using airbrussh format.")
#NB Not sure if blue would work here because `info` already makes the output gray
normal_formatter.info("Verbose output is being written to #{blue(@log_file)}.")
else
print_line config.banner
end
end Anyway, hope this is of some help, happy to look at a PR if you have time to work on it. |
@robd Thanks for the feedback. Agreed on all points. My only concern is that I'm not sure the |
Done in 008fb47. |
Closed via #38 |
Here's an idea suggested by @robd:
Perhaps how this could work is that we introduce a new formatter to handle the logging duplication. In other words, logging events come into this formatter and are duplicated and emitted to multiple destination formatters.
This "dispatcher" would eliminate the need for dealing with the
Pretty
logger insideAirbrussh::Formatter
itself, which would simplify the code and tests quite a bit.As @robd mentions, the one coupling that still remains is the "last 20 lines of output" problem. Perhaps a separate decorator could handle the responsibility of buffering
Pretty
's IO? Sounds like some more discussion needed on this point.Related:
In any case, I think it makes sense to introduce the multi-formatter handling in airbrussh first, and then we can contribute it to SSHKit if it proves to be flexible and useful.
The text was updated successfully, but these errors were encountered: