Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indentation in Rails logs

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?

like image 312
Timitry Avatar asked Oct 25 '18 06:10

Timitry


Video Answer


1 Answers

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

like image 182
Vasfed Avatar answered Oct 31 '22 19:10

Vasfed