I have set up the following using this: Ruby - share logger instance among module/classes
EDIT: Based on the comments below, I updated the code but still have issues logging.
module Logging
# in classes needing to be logged use 'include Logger'
require 'logger'
require 'remote_syslog_logger'
require_relative 'env'
class << self
def logger
return @logger if @logger
if ENV['ENVIRONMENT'] == 'production' #may need to change this
@logger ||= Logger.new($stdout)
@logger.level = Logger::WARN
@logger.datetime_format = "%N "
elsif ENV['ENVIRONMENT'] == 'development'
binding.pry
#$logger = Logger.new(STDOUT)
@logger = RemoteSyslogLogger.new('logs2.papertrailapp.com',39257)
@logger.level = Logger::DEBUG
@logger.datetime_format = "%N "
end
end
def logger=(logger)
@logger = logger
end
end
# Addition
def self.included(base)
class << base
def logger
Logging.logger
end
end
end
def logger
Logging.logger
end
end
How I log:
class CronCheck
require_relative 'module_logger.rb'
include Logging
def self.run
begin
logger.debug "**** running cron_check_schedule.rb #{Time.now} #{Time.now.to_i}****"
rescue
end
end
Question: How can I modify the module so that this type of logic can be defined once, and all I have to do is pass an ENV value for all the classes and methods to log in the same way?
I get an error at logger.debug: undefined method `debug' for "%N ":String
Your code is almost exactly right. What you need to do, though, is set Logging.logger
, not $logger
:
def self.instantiate_logger
logger = Logger.new(STDOUT)
logger.datetime_format = "%N "
if ENV['ENVIRONMENT'] == 'production'
logger.level = Logger::WARN
elsif ENV['ENVIRONMENT'] == 'development'
logger.level = Logger::DEBUG
end
Logging.logger = logger
end
It's not clear from your question where this method lives, but it should be somewhere you can call it during your app's initialization.
You'll notice that I removed the code related to Pry; since that code's not directly related to logging, it should probably go somewhere else.
I would make one more improvement, though, which is to make it more declarative by putting the log levels in a hash keyed by their respective environments:
LOG_LEVELS = {
"production" => Logger::WARN,
"development" => Logger::DEBUG
}
def self.instantiate_logger
Logging.logger = Logger.new(STDOUT).tap do |logger|
logger.datetime_format = "%N "
logger.level = LOG_LEVELS[ENV['ENVIRONMENT']] || LOG_LEVELS["development"]
end
end