When logging custom information, e.g. in a rake
-task, I'd like to indent the log lines for better readability. For example:
Seeding database...
Importing xyz.csv...
Skipping row 5 due to invalid value 'Unknown' in column 'year'
Finished importing xyz.csv
Finished seeding database
In my seeds.rb
, I use the following for logging:
logger = Logger.new(STDOUT)
logger.info('Seeding database...')
However, the logging of Skipping row 5...
takes place in a service, which does not necessarily have to be called from the seeds.rb
, but could be called from anywhere. Thus I can not hardcode the correct indentation (which sounds like a bad idea, anyway).
One possibility would be to keep an "indentation counter", which I could increase when starting to import a file and decrease when finishing. I'm unsure though how to access this from anywhere in my application, or if this is the best solution. Any ideas?
Better solution is to provide your service object with a logger object along with data to process. This way it does not have to know anything about your logger preferences.
And use something like:
require 'logger'
class IndentedLogger < Logger
INDENTATION_STR = ' '.freeze
attr_accessor :indentation
def initialize(io, *args, **params)
self.indentation = 0
super
end
def indented
return self.dup.tap{|l| l.indentation += 1 } unless block_given?
self.indentation += 1
yield self
self.indentation -= 1
end
protected
def format_message(severity, datetime, progname, msg)
(@formatter || @default_formatter).call(severity, datetime, progname, "#{INDENTATION_STR*indentation}#{msg}")
end
end
# Example:
logger = IndentedLogger.new(STDOUT)
logger.info "Foo"
logger.indented{
logger.info "Foo"
logger.indented.info "Indented even more"
}
logger.info "Foo"
And for service call - YourService.new(some_data, logger: logger.indented).process_or_whatever
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With