Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log to different files based on logging level using Ruby logger

Tags:

logging

ruby

I'm writing a rake, just wondering if I can configure Ruby logger, to log to different files based on different logging level.

E.g.

# log to info.log
logger.info "processing: 1/10"
logger.info "processing: 2/10"
logger.info "processing: 3/10"
...

# log to error.log
logger.error "Validation failed on :email"
logger.error "Validation failed on :name"

Update

I was gonna find an inherent solution, and looks like there is none. Thanks for @spickermann's quick answer, and I'll flow his thought to tweak my own version.

Here is the final code, if someone need it.

require 'logger'

class DistinctFileLogger
  LOG_LEVEL = [:debug , :info , :warn , :error , :fatal , :unknown]

  def initialize(path)
    @loggers = {}
    LOG_LEVEL.each do |level|
      @loggers[level] = Logger.new(path)
    end
  end

  LOG_LEVEL.each do |level|
    define_method(level) do |message|
      @loggers[level].send(level, message)
    end

    define_method("set_#{level}_path") do |path|
      @loggers[level] = Logger.new(path)
    end
  end
end

logger = DistinctFileLogger.new(STDOUT)
logger.set_error_path("{path_to}/error.log")

logger.info "processing: 1/10"
logger.info "processing: 2/10"
logger.info "processing: 3/10"

# STDOUT
# I, [2015-12-10T22:30:06.749612 #63303]  INFO -- : processing: 1/10
# I, [2015-12-10T22:30:06.749672 #63303]  INFO -- : processing: 2/10
# I, [2015-12-10T22:30:06.749692 #63303]  INFO -- : processing: 3/10

logger.error "Validation failed on :email"
logger.error "Validation failed on :name"

# error.log
# # Logfile created on 2015-12-10 22:30:06 +0800 by logger.rb/47272
# E, [2015-12-10T22:30:06.749708 #63303] ERROR -- : Validation failed on :email
# E, [2015-12-10T22:30:06.749729 #63303] ERROR -- : Validation failed on :name
like image 537
ifyouseewendy Avatar asked Dec 10 '15 12:12

ifyouseewendy


1 Answers

Define your own custom logger class:

require 'logger'

class DistinctFileLogger
  LOG_LEVEL = [:debug , :info , :warn , :error , :fatal , :unknown]

  def initialize(path)
    @loggers = {}

    LOG_LEVEL.each do |level|
      @loggers[level] = Logger.new("#{path}/#{level}.log")
    end
  end

  LOG_LEVEL.each do |level|
    define_method(level) do |message|
      @loggers[level].send(level, message)
    end
  end
end

Then configure your app to use this custom logger instead of the original. In Rails – for example - this– can be done in your environment config:

Rails.logger = DistinctFileLogger.new(Rails.root.join('log'))
like image 52
spickermann Avatar answered Nov 15 '22 03:11

spickermann